0

I know I need to bind my varaible for unwrap but the problem is my value is not reconized but present.

This is my code :

surveyW.karmaWin = Int(endedSurvey["karma"].string!)

endedSurvey is a array dictionary of my JSON backend. I get a Unexpectedly found nil while unwrapping an Optional value error. I specify that I force the unwrapping to show you my problem.

The problem is my array contains the karma value. I show you the screen of the value:

So we can see that the value existing. Why I get a Unexpectedly found nil...?

halfer
  • 19,824
  • 17
  • 99
  • 186
Louis Brahmi
  • 834
  • 2
  • 9
  • 21
  • 3
    If endedSurvey is an array you need to access the element first and then it's key endedSurvey[1] will have key value pair of "karma" not endedSurvey. – Mukul More Nov 22 '18 at 08:04
  • 2
    Possible duplicate of [What does "fatal error: unexpectedly found nil while unwrapping an Optional value" mean?](https://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) – Kamran Nov 22 '18 at 08:13
  • @MukulMore it is obvious from screenshot that it's a `Dictionary`, not an `Array`. – inokey Nov 22 '18 at 08:14
  • I read his comment saying endedSurvey is an array. so commented that @inokey – Mukul More Nov 22 '18 at 08:17
  • 2
    I would recommend to switch from SwiftyJSON to `Decodable`. – Sulthan Nov 22 '18 at 08:26
  • @inokey My bad this is a `Dictionary` ! – Louis Brahmi Nov 22 '18 at 08:56
  • 1
    But if you want to keep using SwiftyJSON, at least please use it the way it's intended: `.string` is the optional getter, whereas `.stringValue` is the non-optional getter. You should not force unwrap `.string` yourself. Works with other types: .int vs .intValue, etc. – Eric Aya Nov 22 '18 at 10:07

3 Answers3

3

The value contained in "karma" is not String. You're trying to force cast it with SwiftyJSON but it tells you it has a nil. You first need to extract value as it is - .int, and after that convert that to something else if needed.

surveyW.karmaWin = endedSurvey["karma"].int
inokey
  • 5,434
  • 4
  • 21
  • 33
1

You can use intValue because SwiftyJSON has two kinds of "getters" for retrieving values: Optional and non-Optional

.string and .int are the optional getters for the String and Int representation of a value, so you have to unwrap it before use

if let fbId = fbJson["id"].string {
print(fbId)
}

If you are 100% sure that there will always be a value, you can use the equivalent of "force unwrap" by using the non-Optional getter and you don't need if let anymore:

let fbId = fbJson["id"].stringValue

In your code :

surveyW.karmaWin = endedSurvey["karma"].intValue
  • This work, but what's different between .int and .intValue ? – Louis Brahmi Nov 22 '18 at 09:08
  • 1
    .int returns an optional int, which is nil if the value is not a real int. And .intValue provides an int no matter what, which means is tries to convert other values to int values and if that's not possible then it returns a 0. – alireza kiani Nov 22 '18 at 20:52
0

endedSurvey["karma"] is an Integer not string and also good way to unwrap an optional is:

if let karma = endedSurvey["karma"] as? Int{
    surveyW.karmaWin = karma
}
Pratyush Pratik
  • 683
  • 7
  • 14
  • This is SwiftyJSON – Sulthan Nov 22 '18 at 08:26
  • 1
    I have given a reply of native feature. Also i want to say that please don't rely on these third party libraries. Native features of apple are awesome and fast. – Pratyush Pratik Nov 22 '18 at 08:28
  • 4
    SwiftyJSON is a decent piece of software that helped a lot before `Codable` became available in Swift 4. Some use case are easier to write in SwiftyJSON than using `Codable`. Anyway, this question is about SwiftyJSON, therefore answer telling "don't use SwiftyJSON" won't be welcome. – Sulthan Nov 22 '18 at 08:31