iOS客户端公共WIFI解决方案

iOS9之后
代替

基础信息获取

1. 获取IP

用于获取ip等系列功能的头文件
#include 
#include 
#include 
#include 
#import 
外网可见的ip地址
- (NSString *) whatismyipdotcom{    
    NSError *error;    
    NSURL *ipURL = [NSURL URLWithString:@"http://www.whatismyip.com/automation/n09230945.asp"];    
    NSString *ip = [NSString stringWithContentsOfURL:ipURL encoding:1 error:&error];    
    return ip ? ip : [error localizedDescription];
}
本地wifi的ip地址
+ (NSString *)localIPAddress
{
    NSString *localIP = nil;
    struct ifaddrs *addrs;
    if (getifaddrs(&addrs)==0) {
        const struct ifaddrs *cursor = addrs;
        while (cursor != NULL) {
            if (cursor->ifa_addr->sa_family == AF_INET && (cursor->ifa_flags & IFF_LOOPBACK) == 0)
            {
                NSString *name = [NSString stringWithUTF8String:cursor->ifa_name];
                if ([name isEqualToString:@"en0"]) // Wi-Fi adapter
                {
                    localIP = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)cursor->ifa_addr)->sin_addr)];
                    break;
                }
            }
            cursor = cursor->ifa_next;
        }
        freeifaddrs(addrs);
    }
    return localIP;
}

2. 获取网卡信息

- (NSDictionary *)getWIFIDic
{
    CFArrayRef myArray = CNCopySupportedInterfaces();
    if (myArray != nil) {
        CFDictionaryRef myDict = CNCopyCurrentNetworkInfo(CFArrayGetValueAtIndex(myArray, 0));
        if (myDict != nil) {
            NSDictionary *dic = (NSDictionary*)CFBridgingRelease(myDict);
            return dic;
        }
    }
    return nil;
}

- (NSString *)getBSSID
{
    NSDictionary *dic = [self getWIFIDic];
    if (dic == nil) {
        return nil;
    }
    return dic[@"BSSID"];
}

- (NSString *)getSSID
{
    NSDictionary *dic = [self getWIFIDic];
    if (dic == nil) {
        return nil;
    }
    return dic[@"SSID"];
}

认证过程中的问题

1. Portal禁止弹出与WIFI自动关闭的问题
正常情况,用户使用iPhone手机连接带有Portal认证的路由器,在连接成功后,iOS系统会在已有列表中随机选择连接指定的网址(例如:www.itools.info)以测试当前路由器是否需要Portal认证。在需要Portal认证的网络,系统会弹出Portal页面,这个时候,如果用关掉portal页面,或者直接切换到其它应用,WIFI网络会直接自动断开。

解决办法是路由器白名单,让路由器放行所有Portal测试的IP,以下为测试的域名:

www.appleiphonecell.com
captive.apple.com
www.itools.info
www.ibook.info
www.airport.us
www.thinkdifferent.us

对应的IP地址:

23.207.103.91
23.33.54.18
23.44.167.91
23.67.183.91
96.7.103.91
23.42.71.91
23.34.105.211
23.59.167.91
23.42.184.50
23.47.232.190
23.77.23.91
23.194.87.91
23.61.91.190
23.218.12.50
23.2.38.95

23.46.135.91
172.225.213.179
218.205.66.94
23.64.251.249
23.58.250.189

将以上所有IP加到路由器的白名单中,即可解决iPhone断开WIFI的问题,但是同时也不自动弹出Portal页面了,用户打开浏览器才会重定向到Portal页面。

2. 已知WIFI名解决方法
如果公司部署的公共WIFI名确定的情况,就比较简单了,不需要配置上述白名单也可以保证WIFI不断开,具体办法是,在程序启动时,向iOS系统注册SSID,方法如下:

//注册一个SSID,注意此方法多次调用时,最后一次有效
- (void)registerNetworkOnlyOneSSIDValidate:(NSString *)ssid
{
    [self registerNetwork:@[ssid]];
}
//注册多个SSID,多次调用,最后一次有效
- (void)registerNetwork:(NSArray *)ssidStringArray
{
    CFArrayRef ssidCFArray = (__bridge CFArrayRef)ssidStringArray;
    if(!CNSetSupportedSSIDs(ssidCFArray)) {
        return;
    }
    CFArrayRef interfaces = CNCopySupportedInterfaces();
    for (int i = 0; i < CFArrayGetCount(interfaces); i++) {
        CFStringRef interface = CFArrayGetValueAtIndex(interfaces, i);
        CNMarkPortalOnline(interface);
    }
}

你可能感兴趣的:(iOS客户端公共WIFI解决方案)