0

I am trying to extract the value from a JSON serialization but getting nil as the result.

App was working under Swift2 so its the conversion to Swift 3 where the issue started.

let jsonResult = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
print(jsonResult!)
let mySuccess = jsonResult?["success"] as? Int
print (mySuccess!)

The print(jsonResult!) gives the following output

{
"full_login" = 0;
"logged_in" = 1;
message = "<null>";
success = 1;
}

So all good so far and my parsing is working and I now have the data from the server.

However print(mySuccess!) gives this output

fatal error: unexpectedly found nil while unwrapping an Optional value

So I understand the output saying that the code found nil while unwrapping, so my issue now is how do I extract the value of the "Success" key as it was behaving under Swift 2 but now not so under Swift 3?

UPDATE

Sneak found a possible issue that success = 1 do not have the "" so will update question answer once I investigate.

timv
  • 3,346
  • 4
  • 34
  • 43
  • Possible duplicate of [JSON Parsing in Swift 3](http://stackoverflow.com/questions/38155436/json-parsing-in-swift-3) –  Feb 09 '17 at 02:29

3 Answers3

1

hi you can use the concept of OPTIONAL BINDING to check for nil values.

let jsonResult = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
print(jsonResult!)
if let mySuccess = jsonResult?["success"] as? Bool 
{
print (mySuccess)
}
else
{
print ("Found nil")
}
Tushar Sharma
  • 2,839
  • 1
  • 16
  • 38
0

Your print log of success = 1; demonstrates that jsonResult?["success"] is not nil. JSONSerialization.jsonObject can only return three things that would display as 1: a String, a Number or value true. As you tried to unwrap it as an Int and it failed, the only left possibilities are that it was a String or a Bool.

You probably have a success as either:

"success": true

Or:

"success": "1"

As such, you may want to do:

let mySuccess = jsonResult?["success"] as? Bool

Or:

let mySuccess = jsonResult?["success"] as? String

Or ask a change in the backend API response.

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • I don't think thats the issue, since he should get the crash in Swift 2 if that was the case (?) not sure tho you may be correct too. –  Feb 09 '17 at 02:36
  • Thanks for that, tried it but did not help. Still, the fatal error as success is still nil. The output has no "" so I think it is the correct format of key value. – timv Feb 09 '17 at 02:41
  • Yes and still reading it but so far did not isolate my issue but I am still reading through it. – timv Feb 09 '17 at 02:43
  • I am not familiar with Swift, but how come your response you are printing reads **success** = 1; without "", and the others have "" in it ? Could that be the issue? You could do an print to check if the Key even exists in the responseDictionary with the method you are assigning it with, if the print says it doesnt exists, you are obviously accessing a "nil" object, which may be the issue with your Json formatted from the backend. Not sure tho. Hope you solve it. GL –  Feb 09 '17 at 02:48
  • 1
    I just came to the same conclusion that the answer is missing the "" after reading your duplicate post thread. I will talk with the server chap and update my answer. Thanks for seeing the possible issue. – timv Feb 09 '17 at 02:52
  • @timv Im glad I could help, I think that is your issue. –  Feb 09 '17 at 03:04
  • 1
    @Sneak the print command is like the NSLog command, it will strip quotes from pure alphanumeric keys or values in a Dictionary. – Cœur Feb 09 '17 at 03:08
  • -Cœur I know, I edited my comment to print way back. However, you are correct! he didn't actually print the **response** he printed the dictionary itself, **after it's been parsed** which I totally forgot this late my brain isnt working good. Good you pointed that out. I will upvote your answer for this, and just cuz I like your profile picture haircut :) @timv you should look at this. –  Feb 09 '17 at 03:15
0

Ok so the comments were really helpful and helped me hone into the problem. I started to look at the missing "" but noticed that when I entered the following code:

for (key, value) in jsonResult!
{
  print (key)
  print (value)
}

I get the following output

logged_in
1
full_login
0
success
1
message
<null>

So there had to be a way to get just the value for success.
This page gave me the solution in the end. I had to use the following code:

let myResult = (jsonResult?["success"])
print("SUCCESS VALUE >> ", myResult!)

This now gives me the value of 1 and all solved. Thanks again for the comments as they helped.

I then had the issue of not realising the success value was a Bool so I had to use the following code to check for true or false:

 if (jsonResult?["success"] as? Bool)!
 {
     okToLogIn = true
     print(okToLogIn)
 }
     else
 {
     okToLogIn = false
     print(okToLogIn)
  }

Now all good and app working again under Swift 3.

timv
  • 3,346
  • 4
  • 34
  • 43