Reputation: 255
Reading about Optional values I was sure that all the bases were covered in my code, but I still get the dreaded unexpectedly found nil while unwrapping an Optional value
.
That makes sense, since I've read: What does “fatal error: unexpectedly found nil while unwrapping an Optional value” mean?. It suggests making the Int
optional, which is what I want:
func myCountUpdate(mainDict: [String : NSObject]) {
let myDict = mainDict["start"] as! [String : CFString]
let myCount = subDict["count"] as? String
let myTotal = Int(myCount)? // nope, it forces me to use non-optional !
// as the other thread suggest it's easy to check for nil with an optional int.
// how the hell can you do that if it won't allow you to make it optional?
if myTotal != nil {
print(myCount!)
let label: String = "\(myCount)"
text = label
} else {
text = nil
}
}
I've tried quite a bunch of things, including using other values to check for nil
, etc. The issue is that the compiler will not allow me to declare the Int
as non-optional, so what are my options? Xcode shows no warnings or suggestions on this issue, so maybe someone here has one - ty.
Upvotes: 1
Views: 887
Reputation: 9136
First unwrap the variable optional myCount
(String?
) to a variable called count
(String
).
let myCount = mainDict["count"] as? String
if let count = myCount {
//..
}
Then try to create a Int
based on the variable count
(String).
Which could return a nil since you could pass Int("Hi")
or Int("1")
.
myTotal = Int(count)
Then after that you will have a variable called myTotal
(Int?
) with the result that you want.
func myCountUpdate(mainDict: [String : Any]) {
let myDict = mainDict["start"] as? [String : Any]
if let myCount = myDict?["count"] as? String {
if let myTotal = Int(myCount) {
print(myTotal)
}
}
if let myCount = myDict?["count"] as? Int {
print(myCount)
}
}
let data = [
"start": [
"count": "1"
]
]
myCountUpdate(mainDict: data) // outputs 1
let data1 = [
"start": [
"count": 1
]
]
myCountUpdate(mainDict: data1) // outputs 1
Upvotes: 2
Reputation: 768
The best approach here is to use swift guards
in order to check if a value is nil.
First, in the second line, where you use the subDict
, its not referenced anywhere else, should it be myDict
?
The thing here is that the cast in let myCount = subDict["count"] as? String
may be returning nil or there is not "count" in subDict. Therefore, when you do Int(myCount!)
, the force unwrapp of myCount
is throwing the exception, since its nil.
You should avoid force unwrappings as much as you can, unless you are 100% sure that the value is not nil. In other cases, you should use the setting of a variable to check if it is not nil.
With your code, an updated version using guard would be the following:
func myCountUpdate(mainDict: [String : NSObject]) {
guard let myDict = mainDict["start"] as? [String : CFString],
let myCount = myDict["count"] as? String,
let myTotal = Int(myCount) else {
text = nil
return
}
print(myTotal)
let label: String = "\(count)"
text = label
}
This is safer, because if any of the conditions in the guard fails, then it's setting the text to nil an ending the method.
Upvotes: 3