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);
}
}