I'm working on a database connection between Swift 3 and a php file.
Sending information to the php will be correctly transfered into the database.
But I'm having an issue when I want to print information from the database into my xcode.
I'm sending this json to my app:
[{"latitude":"51.430536341034","longitude":"5.45947450542819"},
{"latitude":"51.4305299243587","longitude":"5.45964865535365"},
{"latitude":"51.4305299243587","longitude":"5.45964865535365"},
{"latitude":"51.4305299243587","longitude":"5.45964865535365"},
{"latitude":"51.4305299243587","longitude":"5.45964865535365"}]
I printed this JSON in xcode with:
print(NSString(data: data!, encoding: String.Encoding.utf8.rawValue)!)
I tried 2 options that were described in other topics at this site, which both were about swift 3 and json problems.
Option 1:
let parsedData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:AnyObject]
When I ran the app, there come's an error:
Signal SGBRT Could not cast value of type '__NSArrayI' (0x1b2a89cc8) to 'NSDictionary' (0x1b2a8a128).
Option 2:
let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! Dictionary<String, AnyObject>
What happens is the same Signal SGBRT with error:
Could not cast value of type '__NSArrayI' (0x1b2a89cc8) to 'NSDictionary' (0x1b2a8a128).
I need to say that I'm not a professional, but I'm a hard learning student with no connections that also program swift. Therefore I hope to get some help here, to finish this function of the app.
If you answer the topic, I would be glad to here some other codes I should try.
Thank you.
From your JSON response that you have added in question, if that was the only response that you need to use [[String: String]] instead of [[String: AnyObject]] because using AnyObject you need to first convert it to String then double, so it is batter if you use [[String: String]]. Now you have array of dictionary so get all coordinates like this way.
let parsedData = try? JSONSerialization.jsonObject(with: data!, options: []) as! [[String:String]]
for dic in parsedData {
if let lat = Double(dic["latitude"]), let long = Double(dic["longitude"]) {
print(lat)
print(long)
}
}
Your JSON clearly says that it is an array of dictionaries, so you should cast it to an array of dictionaries [[String: AnyObject]]. Already mentioned in comments. Try below, it might help you:
//First you should check for data whether it has value
if let data = data {
//This gives you an array of dictionaries as per your JSON data. So safer side try to 'guard let' it so that it should not crash if your JSON data is nil
guard let parsedDataArray = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [[String: AnyObject]] else { return }
//Here you can enumerate through your array to get each dictionary
for parsedDict in parsedDataArray {
//This gives the value of latitude
if let latitude = parsedDict["latitude"] {
print(latitude)
}
//And this is for "longitude"
if let longitude = parsedDict["longitude"] {
print(longitude)
}
}
}
Related
I want to run the same line of code but incrementing the number "prodottiNome_prodotto0" and forKey: ("nome_prodotto0") always.
let prodotti = jsonData.value(forKey: "prodotti") as! NSDictionary
let prodottiNome_prodotto0 = prodotti.value(forKey: "nome_prodotto0") as! String
self.defaultValues.set(prodottiNome_prodotto0, forKey: "nome_prodotto0")
nome_prodotto0 refers to the result of a return in php ------------>
"prodotti":{"nome_prodotto0":"farina","nome_prodotto1":"dfd"}
If I understand what you're asking, your code might look like this:
let max = 50 //Or whatever limit you want to use
for i in 0...max {
let key = "nome_prodotto" + String(i)
//Use `if let` so you don't crash if a value is not a string
//Don't use `value(forKey:)` on a dictionary. That's a KVO method
if let value = prodotti[key] as? String {
self.defaultValues.set(value, forKey: key)
{
}
I am trying to decode a base64 string in Xcode(Swift), but the decoding always returns nil. I have tried padding the string to a multiple of 4, as well as using these different decoding options below, but any decently long string (about 300 words) will always return nil when unwrapping.
let decodedData = NSData(base64EncodedString: artitxt, options: NSDataBase64DecodingOptions(rawValue: 0)),
decodedString = NSString(data: decodedData!, encoding: NSUTF8StringEncoding)
articletext.text = (decodedString) as! String
as well as
let decodedData = NSData(base64EncodedString: artitxt, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters),
decodedString = NSString(data: decodedData!, encoding: NSUTF8StringEncoding)
articletext.text = (decodedString) as! String
artitxt is the base64 encoded string returned by my database, and articletext is a text view in my view controller. The string is encoded by PHP before being placed into my SQL database. If I encode the same string with base64encode.org, and decode it in my app, no error occurs. So, what about PHP base64encode is throwing this error- and more importantly how can I decode this string properly? Any help would be greatly appreciated as this has become a huge road block for me. Thanks!
If I print decodedData, I end up with this, but I do not have the knowledge to make sense of it.
<54686520 70757270 6f736520 6f662074 68697320 6c616220 65787065 72696d65 6e742077 61732074 6f207465 73742074 68652065 66666563 74206f66 20656e7a 796d6520 636f6e63 656e7472 6174696f 6e2c2073 75627374 72617465 20636f6e 63656e74 72617469 6f6e2c20 74656d70 65726174 7572652c 20616e64 20704820 6f6e2061 6e20656e 7a796d65 92732072 61746520 6f662061 63746976 6974792e 20466f72 20656163 68207465 73742061 6e642065 61636820 74726961 6c207765 20757365 6420686f 6c652070 756e6368 65642070 69656365 73206f66 2066696c 74657220 70617065 722e2054 68657365 20706965 63657320 6f662066 696c7465 72207061 70657220 77657265 20746865 6e207461 6b656e20 6f6e6520 6279206f 6e652077 69746820 666f7263 65707320 616e6420 696d6d65 72736564 20696e74 6f206f75 72206361 74616c61 73652c20 706f7461 746f2065 6e7a796d 65206578 74726163 742c2066 6f722035 20736563 6f6e6473 2e205468 65206669 6c746572 20706170 65722077 61732074 68656e20 626c6f74 74656420 61676169 6e737420 61207061 70657220 746f7765 6c20666f 72203130 20736563 6f6e6473 20616e64 20707573 68656420 746f2074 68652062 6f74746f 6d2e204f 6e65206f 66207468 65207072 6f647563 7473206f 66207468 65207265 61637469 6f6e2074 68617420 666f726d 73206973 206f7879 67656e20 6761732c 20776869 63682063 61757365 73207468 65206669 6c746572 20706170 65722074 6f207269 73652074 6f207468 6520746f 70206166 74657220 61206365 72746169 6e20616d 6f756e74 206f6620 74696d65 2e205765 20726563 6f726465 64207468 61742074 696d6520 616e6420 64696420 31206469 76696465 64206279 2074696d 6520746f 2066696e 64207468 65207261 7465206f 66206163 74697669 74792e20 466f7220 6d792067 726f7570 92732074 6573742c 20776520 74657374 65642074 68652065 66666563 74206f66 20737562 73747261 74652063 6f6e6365 6e747261 74696f6e 206f6e20 72617465 206f6620 61637469 76697479 2e205765 20696e63 72656173 65642073 75627374 72617465 20285065 726f7869 64652920 636f6e63 656e7472 6174696f 6e206265 74776565 6e203020 616e6420 33207065 7263656e 7420696e 20313030 206d4c20 6265616b 65727320 6f766572 20382064 69666665 72656e74 20747265 61746d65 6e747320 616e6420 636f6e63 6c756465 64207468 61742061 73207375 62737472 61746520 636f6e63 656e7472 6174696f 6e20696e 63726561 7365732c 20726174 65206f66 20616374 69766974 7920696e 63726561 7365732e 20466f72 20656e7a 796d6520 636f6e63 656e7472 6174696f 6e207765 20636f6e 636c7564 65642074 68617420 616e2069 6e637265 61736520 696e2063 6f6e6365 6e747261 74696f6e 20636175 73657320 616e2069 6e637265 61736520 696e2072 61746520 6f662061 63746976 6974792e 20466f72 20704820 77652063 6f6e636c 75646564 20746861 74206f70 74696d75 6d207048 20666f72 20746865 20686967 68657374 20726174 65206f66 20616374 69766974 79207065 616b7320 61742037 20616e64 20392028 6d617920 68617665 20657272 6f72292e 20466f72 2074656d 70657261 74757265 20776520 636f6e63 6c756465 64207468 61742074 6865206f 7074696d 616c2074 656d7065 72617475 72652069 73206172 6f756e64 20333720 64656772 65657320 63656c73 6975732c 20776869 63682069 73207468 65206875 6d616e20 626f6479 2074656d 70657261 74757265 2e202045 6e7a796d 65732061 72652070 726f7465 696e7320 74686174 20636174 616c7973 65207265 61637469 6f6e7320 62792070 726f7669 64696e67 20616e20 61637469 76652073 69746520 666f7220 73756273 74726174 6573>
Using a PHP file, I echoed data from a MySQL database in the following format: [{"longitude":"-122.031","latitude":"37.3323”}]
In my Swift file, I use NSJSONSerialization.JSONObjectWithData() to create a JSON dictionary that looks like the following
(
{
latitude = "37.3323";
longitude = "-122.031";
}
)
If I wanted to store the individual dictionary values inside variables, I believe the following snippet of Swift code would work
class Location: NSObject {
var latitude: String?
var longitude: String?
}
var locations = [Location]()
if let locationDictionary = jsonDictionary["coordinates"] as? [String: AnyObject] {
let location = Location()
location.setValuesForKeysWithDictionary(locationDictionary)
print(location.latitude, location.longitude)
}
The only problem I’m having is that I need my JSON dictionary to look like
(
coordinates = {
latitude = "37.3323";
longitude = "-122.031";
}
)
but I don’t know what steps to take to achieve this.
You would have to make your JSON like this:
[{"coordinates":{"longitude":"-122.031","latitude":"37.3323"}}]
which is an array of dictionaries, where each dictionary contains another one.
And here is your code adapted for the new format:
if let json = try? NSJSONSerialization.JSONObjectWithData(data, options: []), // your source may differ, I'm just using this line for my example
content = json as? [[String:AnyObject]] { // the array of dictionaries
for item in content {
if let locationDictionary = item["coordinates"] as? [String: AnyObject] { // the dictionary inside the dictionary
let location = Location()
location.setValuesForKeysWithDictionary(locationDictionary)
print(location.latitude, location.longitude)
}
}
}
I'm passing a large set of strings to my server from iOS (Swift) to a PHP file via POST. Unfortunately, if a user places an ampersand (&) in a field, the rest of the field is lost. I understand why (& signifies the next field in the message) but I'm not sure how to fix.
func UploadToSql(plan: LessonPlan, isNew: Bool, callBack: ((data: NSData!, response: NSURLResponse!, error: NSError!) -> Void)?) {
let url = NSURL(string: "https://myserver.com/receive.php")!
var request:NSMutableURLRequest = NSMutableURLRequest(URL:url)
var bodyData = "Author=\(plan.author)&title=\(plan.title)&grade=\(plan.grade)&date=\"\(plan.date)\"&element1=\(plan.element1)&objective1=\(convertedFields[0])&element2=\(plan.element2)&objective2=\(convertedFields[1])&element3=\(plan.element3)&objective3=\(convertedFields[2])&coreProcess1=\(plan.coreProcess1)&coreStrand1=\(plan.coreStrand1)&coreStandard1=\(plan.coreStandard1)&coreProcess2=\(plan.coreProcess2)&coreStrand2=\(plan.coreStrand2)&coreStandard2=\(plan.coreStandard2)&coreProcess3=\(plan.coreProcess3)&coreStrand3=\(plan.coreStrand3)&coreStandard3=\(plan.coreStandard3)&media1=\(plan.media1)&media2=\(plan.media2)&media3=\(plan.media3)&media4=\(plan.media4)&media5=\(plan.media5)&media6=\(plan.media6)&repertoire1=\(convertedFields[3])&repertoire2=\(convertedFields[4])&repertoire3=\(convertedFields[5])&process=\(convertedFields[6])&assessment=\(convertedFields[7])&stateCat1=\(plan.stateCat1)&stateCat2=\(plan.stateCat2)&stateCat3=\(plan.stateCat3)&stateStand1=\(plan.stateStand1)&stateStand2=\(plan.stateStand2)&stateStand3=\(plan.stateStand3)&comment=\(plan.comment)&shared=\(sharedInt!)&authorName=\(plan.authorName)" + planID
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
println("error=\(error)")
return
}
println("response = \(response)")
callBack?(data: data, response: response, error: error)
return
}
task.resume()
}
Typically for a webrequest like that it uses % followed by the ascii hex value. The hex value for & is 26, so it would be %26
google.com/#q=red%26white is example of a google search for red&white, which uses that replacement
Its called URL encoding or percent encoding and here is another question with an answer on how to do more broad URL encoding: stackoverflow.com/questions/24551816/swift-encode-url
Note that you would have to URL encode each element you were interpolating into the string, not the whole result string, as you want to keep your &'s that separate parameters.
This one is working for me. I am also using PHP/MySQL with NSURLSession.
func stringByAddingPercentEncodingForFormData(plusForSpace: Bool=false) -> String? {
let unreserved = "*-._"
let allowed = NSMutableCharacterSet.alphanumericCharacterSet()
allowed.addCharactersInString(unreserved)
if plusForSpace {
allowed.addCharactersInString(" ")
}
var encoded = stringByAddingPercentEncodingWithAllowedCharacters(allowed)
if plusForSpace {
encoded = encoded?.stringByReplacingOccurrencesOfString(" ",
withString: "+")
}
return encoded
}
Found above function from this link: http://useyourloaf.com/blog/how-to-percent-encode-a-url-string/.
How do I get/extract datas from bracket/object in iOS swift???
I used println(datas) to display in Xcode6 console log:
Optional({"status":"fail","message":"Invalid Username or Password"})
note:
server code: php language.
I want to get this datas from that object or array. I don't know what that is.
I want to specifically display status in a specific label.
I want swift code if possible. Thank you very much!!! :D hehe
You PhP code returns a JSON, its like this:
{
"status":"fail",
"message":"Invalid Username or Password"
}
Its an NSDictionary type data, So receive it in an NSDictionary, lets call it responseData.
Then If you want to get status then write this:
let status = responseData ["status"]! as String
For message :
let message = responseData ["message"]! as String
From your provided code:
var task = session.dataTaskWithRequest(request, completionHandler: {data, response, error -> Void in
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
let status = jsonResult ["status"]! as String
println(status)
let message = jsonResult ["message"]! as String
println(message)
})
Hope this helps.. :)
Try it
var jsonText = //your json text
var data : Dictionary<NSObject, NSObject> =
NSJSONSerialization.JSONObjectWithData(text.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!, options: nil, error: nil)