iOS客戶端公共WIFI解決方案

iOS9之后 <SystemConfiguration/CaptiveNetwork.h>
<NetworkExtension/NEHotspotHelper.h>代替

基礎(chǔ)信息獲取

1. 獲取IP

用于獲取ip等系列功能的頭文件
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
#include <ifaddrs.h>
#import <dlfcn.h>
外網(wǎng)可見(jiàn)的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. 獲取網(wǎng)卡信息

- (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"];
}

認(rèn)證過(guò)程中的問(wèn)題

1. Portal禁止彈出與WIFI自動(dòng)關(guān)閉的問(wèn)題
正常情況,用戶使用iPhone手機(jī)連接帶有Portal認(rèn)證的路由器,在連接成功后,iOS系統(tǒng)會(huì)在已有列表中隨機(jī)選擇連接指定的網(wǎng)址(例如:www.itools.info)以測(cè)試當(dāng)前路由器是否需要Portal認(rèn)證。在需要Portal認(rèn)證的網(wǎng)絡(luò),系統(tǒng)會(huì)彈出Portal頁(yè)面,這個(gè)時(shí)候,如果用關(guān)掉portal頁(yè)面,或者直接切換到其它應(yīng)用,WIFI網(wǎng)絡(luò)會(huì)直接自動(dòng)斷開(kāi)。

解決辦法是路由器白名單,讓路由器放行所有Portal測(cè)試的IP,以下為測(cè)試的域名:

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

對(duì)應(yīng)的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斷開(kāi)WIFI的問(wèn)題,但是同時(shí)也不自動(dòng)彈出Portal頁(yè)面了,用戶打開(kāi)瀏覽器才會(huì)重定向到Portal頁(yè)面。

2. 已知WIFI名解決方法
如果公司部署的公共WIFI名確定的情況,就比較簡(jiǎn)單了,不需要配置上述白名單也可以保證WIFI不斷開(kāi),具體辦法是,在程序啟動(dòng)時(shí),向iOS系統(tǒng)注冊(cè)SSID,方法如下:

//注冊(cè)一個(gè)SSID,注意此方法多次調(diào)用時(shí),最后一次有效
- (void)registerNetworkOnlyOneSSIDValidate:(NSString *)ssid
{
    [self registerNetwork:@[ssid]];
}
//注冊(cè)多個(gè)SSID,多次調(diào)用,最后一次有效
- (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);
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容