Sam Luther
Sam Luther

Reputation: 1190

Swift check NSDate is not nil

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

Answers (1)

Martin R
Martin R

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

Related Questions