Reputation: 1190
I'm getting a value from userDefaults which might be nil or might be an NSDate, so I want to check since I need to act on that date. How would I correctly do the check?
let timeAtQuit: NSDate = (userDefaults.objectForKey("timeAtQuit") as NSDate)
if(timeAtQuit){ Type 'NSDate' does not conform to protocol 'BooleanType'
if(timeAtQuit != nil){ // 'NSDate' is not convertible to 'UInt8'
another attempt:
var timeAtQuit:NSDate? = (userDefaults.objectForKey("timeAtQuit") as NSDate)
if(timeAtQuit != nil){
let timeSinceQuit:Double = timeAtQuit.timeIntervalSinceNow // 'NSDate?' does not have a member named 'timeIntervalSinceNow'
}
Upvotes: 0
Views: 3606
Reputation: 539795
Use optional binding (if let
) with an optional cast (as?
):
if let timeAtQuit = userDefaults.objectForKey("timeAtQuit") as? NSDate {
println(timeAtQuit)
} else {
// default value is not set or not an NSDate
}
With
let timeAtQuit: NSDate = (userDefaults.objectForKey("timeAtQuit") as NSDate)
you are forcefully casting the return value to NSDate
, so this
will crash at runtime if the value is not set or not an NSDate
.
The same happens in
var timeAtQuit:NSDate? = (userDefaults.objectForKey("timeAtQuit") as NSDate)
It does not help that the expression is assigned to an optional NSDate?
, the crash already occurs when evaluating the right-hand side.
The compiler error at
let timeSinceQuit:Double = timeAtQuit.timeIntervalSinceNow
occurs because timeAtQuit
is an optional here, so you would have to
unwrap it
let timeSinceQuit:Double = timeAtQuit!.timeIntervalSinceNow
Upvotes: 10