Search code examples
iosswiftbit-fieldsbitmask

How to check bitfields (SCNetworkReachabilityFlags in particular) for flags in Swift?


I have a SCNetworkReachabilityFlags variable and want to check it for particular values, e.g. if the network is reachable via WWAN.

The SCNetworkReachabilityFlags type is a typealias for UInt32 and the various options are defined as Int variables.

Using Objective-C you could do the following:

if (flags & kSCNetworkReachabilityFlagsIsWWAN) {
 // do stuff
}

In Swift if I try this:

if reachabilityFlags & kSCNetworkReachabilityFlagsIsWWAN {
 // do stuff
}

you get a compiler error: Could not find an overload for '&' that accepts the supplied arguments.

I've read some other questions where the bitfield options where defined as a RawOptionSet struct. This hasn't been done in SCNetworkReachability.

How to you check for flags in Swift?


Solution

  • That error is actually complaining not about the arguments of your flags-check, but about the return value. An if statement expects a boolean (or at least something conforming to Logical), but the & operator for two Int values returns an Int. You just need a comparison in your if statement:

    let flags = kSCNetworkReachabilityFlagsReachable
    if 0 != flags & kSCNetworkReachabilityFlagsReachable {
        println("flags contains kSCNetworkReachabilityFlagsReachable")
    }
    

    Since SCNetworkReachabilityFlags and the constants are (strangely) of different types, you'll need to do some casting to make the comparison work:

    let reachabilityFlags:SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(kSCNetworkReachabilityFlagsReachable)
    if 0 != reachabilityFlags & SCNetworkReachabilityFlags(kSCNetworkReachabilityFlagsReachable) {
        println("reachabilityFlags contains kSCNetworkReachabilityFlagsReachable")
    }