Mike Akers
Mike Akers

Reputation: 12257

How do I compare an NSNumber to a swift enumeration value?

I'm trying to do a simple comparison of a value received via an NSNotification, and an enumeration value. I have something that works, but I can't believe that this is the right way to be doing this. Basically the solution I ended up with was converting the NSNumber to an Int, and also getting the enum value's rawValue, wrapping it in an NSNumber and then getting the integerValue of that.

Everything else I tried resulted in compiler errors about not being able to convert between Uint 8 and Int or something similar.

    observer = NSNotificationCenter.defaultCenter().addObserverForName(AVAudioSessionRouteChangeNotification, object: nil, queue: mainQueue) { notification in

        println(AVAudioSessionRouteChangeReason.NewDeviceAvailable.toRaw())

        if let reason = notification.userInfo[AVAudioSessionRouteChangeReasonKey!] as? NSNumber  {
            if (reason.integerValue == NSNumber(unsignedLong:AVAudioSessionRouteChangeReason.NewDeviceAvailable.toRaw()).integerValue) {
                self.headphoneJackedIn = true;
            } else if (reason.integerValue == NSNumber(unsignedLong:AVAudioSessionRouteChangeReason.OldDeviceUnavailable.toRaw()).integerValue) {
                self.headphoneJackedIn = false;
            }
            self.updateHeadphoneJackLabel()
        }
    }

Upvotes: 2

Views: 6402

Answers (1)

Martin R
Martin R

Reputation: 540055

This should work:

if reason.integerValue == Int(AVAudioSessionRouteChangeReason.NewDeviceAvailable.rawValue) {
    // ...
}

Remark: The AVAudioSessionRouteChangeReason enumeration uses UInt as raw value type, so one could expect that this works without an explicit conversion:

if reason.unsignedIntegerValue == AVAudioSessionRouteChangeReason.NewDeviceAvailable.rawValue {

}

However, as of Xcode 6 beta 4, NSUInteger is mapped to Swift's Int in OS X and iOS system frameworks, which means that both integerValue and unsignedIntegerValue return an Int, and an explicit conversion is needed in any case.

Alternatively, you could create an enumeration value from the number (as already suggested by @ColinE in a comment) and then use switch case:

if let r = AVAudioSessionRouteChangeReason(rawValue: UInt(reason.integerValue)) {
    switch r {
    case .NewDeviceAvailable:
        // ...
    case .OldDeviceUnavailable:
        // ...
    default:
        // ...
    }
} else {
    println ("Other reason")
}

For the same reason as above, an explicit UInt conversion is necessary here as well.

Upvotes: 8

Related Questions