I'm watching the Standford Swift lecturers on ItunesU and have some trouble in understanding.
The lecturer is typecasting a String to a Double at one point.
He did it as follows:
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
display.text is a UILabel
Anyhow, when I'm doing it like this my app crashes and I get the following error:
fatal error: unexpectedly found nil while unwrapping an Optional value
When I typecast the String like this:
(display.text! as NSString).doubleValue
it works fine.
I know there must be an optional var anywhere but I'm not that into it to say what is wrong at this point.
I'm happy for every hint.
The issue is your display.text
doesn't have a valid number in it's text. So it'll return nil.
So your expression will become:
return nil!.doubleValue
And it'll definitely crash.
For converting a String
to double
your second approach is more suitable. Means using:
(display.text! as NSString).doubleValue
is a better approach for this case.
Reference : NSNumberFormatter Class Reference
- numberFromString:
Returns an NSNumber object created by parsing a given string.
Declaration
Swift
func numberFromString(_ string: String) -> NSNumber?
Objective-C
- (NSNumber *)numberFromString:(NSString *)string
Parameters
string
An NSString object that is parsed to generate the returned number
object.
Return Value
An NSNumber object created by parsing string using the receiver’s
format. Returns nil if there are no numbers in the passed string.
Discussion
Any leading spaces in a string are ignored. For example, the strings “
5” and “5” are handled in the same way.
Mika, I just figured out why my calculator program is crashing with the same error message as you. Remember when we created the enter key, it was still "bound" to the appendDigit function and we had to option/right click on the button to break the connection. I was fighting the same issue as you, and it turned out that I had copy/pasted my operation keys and all of them were still connected to the appendDigit function. That meant every time I hit the "x" key, it was sending a non-number to the appendDigit function which when unwrapped was the equivalent of "nil".
Hope that helps.
Wilton
In the first form, numberFromString
returns nil
if display.text
does not contain a number.
My guess is that in this first case your display.text
is not initialized with a number. So numberFromString
return a nil
that you are trying to unwrap using !
. This throw the error.
In the second form, you are typecasting as NSString
no matters what is the content (empty, "1.0", "foo"...) and then calling doubleValue
which will return 0.0 if the string doesn’t begin with a valid text (different than a number).This doesn't throw an error, in the worst case it will return 0.0.
I'm currently following the lectures and ran into the same issue. user3763062 and I had the same problem: we both accidentally left the enter key bounded to appendDigit function.
Deleting the connection solved my issue.
Well, I guess you learning the Swift programming and making your first calculator.
If I'm right, you getting this crash because you forgot to delete a message that your Enter button sending. In this case you getting an error because Enter symbol does not represent a number.
I was running into the same issue when I tested the app on my iPhone. The problem was the dot, for decimal numbers. My iPhone region was set to Romania, where we use comma to separate decimals and I believe the numberFromString depends on the region when making transformations. After I changed the region to US, the nil exception did not appear.
You can use a conditional cast to Double and nil coalescing operator to make sure it does't return nil as follow:
var myNumber = NSNumberFormatter().numberFromString("10.5") as? Double ?? 0
println(myNumber) // 10.5
myNumber = NSNumberFormatter().numberFromString("10") as? Double ?? 0
println(myNumber) // 10.0
myNumber = NSNumberFormatter().numberFromString("abc") as? Double ?? 0
println(myNumber) // 0.0
For me, this works:
return Double(display.text!)!