I'm trying to process a JSON object, using a guard
statement to unwrap it and cast to the type I want, but the value is still being saved as an optional.
guard let json = try? JSONSerialization.jsonObject(with: data) as? [String:Any] else {
break
}
let result = json["Result"]
// Error: Value of optional type '[String:Any]?' not unwrapped
Am I missing something here?
Optional binding is a construct that lets you safely access the optional's value. If you're absolutely certain an optional contains a value, you can take a shortcut by force unwrapping the value stored in the optional. To force unwrap an optional, we append an exclamation mark to the name of the variable or constant.
A common way of unwrapping optionals is with if let syntax, which unwraps with a condition. If there was a value inside the optional then you can use it, but if there wasn't the condition fails. For example: if let unwrapped = name { print("\(unwrapped.
Even though Swift isn't sure the conversion will work, you can see the code is safe so you can force unwrap the result by writing ! after Int(str) , like this: let num = Int(str)! Swift will immediately unwrap the optional and make num a regular Int rather than an Int? .
You can unwrap optionals in 4 different ways: With force unwrapping, using ! With optional binding, using if let. With implicitly unwrapped optionals, using !
try? JSONSerialization.jsonObject(with: data) as? [String:Any]
is interpreted as
try? (JSONSerialization.jsonObject(with: data) as? [String:Any])
which makes it a "double optional" of type [String:Any]??
.
The optional binding removes only one level, so that json
has
the type [String:Any]?
The problem is solved by setting parentheses:
guard let json = (try? JSONSerialization.jsonObject(with: data)) as? [String:Any] else {
break
}
And just for fun: Another (less obvious?, obfuscating?) solution is to use pattern matching with a double optional pattern:
guard case let json?? = try? JSONSerialization.jsonObject(with: data) as? [String:Any] else {
break
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With