iPhone Wifi on or off?

2019-01-12 00:57发布

Within iOS framework, how can one check if the Wifi radio is enabled by the user or not? Please note that I'm not interested in the reachability through Wifi but rather if the device is turned off by the user. Thanks.

标签: iphone ios wifi
6条回答
霸刀☆藐视天下
2楼-- · 2019-01-12 01:38

As mentioned in comment by @magma, you may have to use Reachability source code. So far based on my experience and what others have been talking, there is NO boolean which can tell you if the user has turned off Wi-Fi in Settings. By checking if the device can reach internet, you just have to deduce and conclude(assume) the user has turned Wi-Fi off.

查看更多
女痞
3楼-- · 2019-01-12 01:38

Based on: http://www.enigmaticape.com/blog/determine-wifi-enabled-ios-one-weird-trick

Wifi status can be determined to be ON/ OFF using C based ifaddress struct from:

ifaddrs.h, and

net/if.h

[Code source: unknown.]

- (BOOL) isWiFiEnabled {

    NSCountedSet * cset = [NSCountedSet new];

    struct ifaddrs *interfaces;

    if( ! getifaddrs(&interfaces) ) {
        for( struct ifaddrs *interface = interfaces; interface; interface = interface->ifa_next) {
            if ( (interface->ifa_flags & IFF_UP) == IFF_UP ) {
                [cset addObject:[NSString stringWithUTF8String:interface->ifa_name]];
            }
        }
    }

    return [cset countForObject:@"awdl0"] > 1 ? YES : NO;
}

Swift 3 version (requires bridging header with #include <ifaddrs.h>):

func isWifiEnabled() -> Bool {
    var addresses = [String]()

    var ifaddr : UnsafeMutablePointer<ifaddrs>?
    guard getifaddrs(&ifaddr) == 0 else { return false }
    guard let firstAddr = ifaddr else { return false }

    for ptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
        addresses.append(String(cString: ptr.pointee.ifa_name))
    }

    freeifaddrs(ifaddr)
    return addresses.contains("awdl0")
}
查看更多
Explosion°爆炸
4楼-- · 2019-01-12 01:41

Using Reachability is the correct way to go.

You cannot access the direct settings within an app that should go on the App Store. That is considered private user territory where an app has no reason to deal with at all.

But without more explanation I do not really see the need to find out the settings.

That is nothing an App should ever be interested or worry about. You have network access or you do not have network access. If none is available then the reason for it does not matter.

You do not ask a question like "Do you not have a Ford?" "Do you not have a BMW?". Instead from a good application design you ask "Do you have a car?"

Also Raechability has nothing to do with the Internet. It tells you if the device is theoretical reachable by over a TCP/IP network. That means some network communication is available. Then you can check what type (e.g. Wifi vs. 3G/LTE). And that is exactly what's Reachability is for.

If you for what ever reason really want to go down if the radios is turned on and it is for a kind of Enterprise app, you can look into the private frameworks, import them and deal with their undocumented methods that are subject to change with any update.

For Wifi it should be: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/PrivateFrameworks/MobileWiFi.framework

查看更多
仙女界的扛把子
5楼-- · 2019-01-12 01:44

PrivateFrameworks is not available in sdk nor is it available to any enterprise developer.

If we know what you want to achieve my knowing the wifi radio power state, we can probably suggest an alternative solution, but from how apple has been with what they expose to developers i don't see this ever becoming possible directly.

Using reachability you can know for sure if wifi is ON but to know if wifi is OFF toss a coin.

查看更多
女痞
6楼-- · 2019-01-12 02:02

iOS has no public API that tells you if Wi-Fi is on or off.

However, you can use the public API CNCopyCurrentNetworkInfo(), available in SystemConfiguration framework, to get info about the current Wi-Fi network. This does not tell you if Wi-Fi is turned on or off but rather if the device is joined to a Wi-Fi network or not. Perhaps this is sufficient for your purposes.

Also note that this API doesn't work in Simulator, as CNCopySupportedInterfaces() always returns NULL.

#include <SystemConfiguration/CaptiveNetwork.h>

BOOL hasWiFiNetwork = NO;
NSArray *interfaces = CFBridgingRelease(CNCopySupportedInterfaces());
for (NSString *interface in interfaces) {
    NSDictionary *networkInfo = CFBridgingRelease(CNCopyCurrentNetworkInfo((__bridge CFStringRef)(interface)));
    if (networkInfo != NULL) {
        hasWiFiNetwork = YES;
        break;
    }
}
查看更多
地球回转人心会变
7楼-- · 2019-01-12 02:04

Swift 2.3 version

func isWifiEnabled() -> Bool {
    var addresses = [String]()

    var ifaddr : UnsafeMutablePointer<ifaddrs> = nil
    guard getifaddrs(&ifaddr) == 0 else { return false }

    var ptr = ifaddr
    while ptr != nil { defer { ptr = ptr.memory.ifa_next }
         addresses.append(String.fromCString(ptr.memory.ifa_name)!)
    }

    var counts:[String:Int] = [:]

    for item in addresses {
        counts[item] = (counts[item] ?? 0) + 1
    }

    freeifaddrs(ifaddr)
    return counts["awdl0"] > 1 ? true : false
}

Swift 4.0 version

func isWifiEnabled() -> Bool {
    var addresses = [String]()

    var ifaddr : UnsafeMutablePointer<ifaddrs>?
    guard getifaddrs(&ifaddr) == 0 else { return false }
    guard let firstAddr = ifaddr else { return false }

    for ptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
        addresses.append(String(cString: ptr.pointee.ifa_name))
    }

    var counts:[String:Int] = [:]

    for item in addresses {
        counts[item] = (counts[item] ?? 0) + 1
    }

    freeifaddrs(ifaddr)
    guard let count = counts["awdl0"] else { return false }
    return count > 1
}
查看更多
登录 后发表回答