接触过ios开发的人应该都知道,对于检测网络连接状态AFN基本上已经够用了,但是最近几年兴起的商超,大型酒店饭店等娱乐场所的portal认证,需要检测手机是否真正能上网!(一种伪联网状态,就是已经连接到了wifi,但是不能真正上网).此时原因是因为ap设备的网关并没有放行,但是这种状态通过AF并不能检测出来.
#试过很多种方法,基于tcp协议的socket通信,基于ICMP协议的ping,基于http协议的网络请求.
下面要讲的就是基于http协议的网络请求来辨别真正的联网状态!
以前写过一遍基于tcp协议的socket通信的,有兴趣的可以翻翻.
#define kAppleUrlTocheckWifi @"http://captive.apple.com"
//检测网络是否可以使用
+(BOOL)checkNetworkCanUse{
// 1.将网址初始化成一个OC字符串对象
NSString *urlStr = kAppleUrlTocheckWifi;
// 如果网址中存在中文,进行URLEncode
NSString *newUrlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// 2.构建网络URL对象, NSURL
NSURL *url = [NSURL URLWithString:newUrlStr];
// 3.创建网络请求
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:3];
// 创建同步链接
NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString* result1 = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
//解析html页面
NSString *str = [self flattenHTML:result1];
//除掉换行符
NSString *nstr = [str stringByReplacingOccurrencesOfString:@"\n" withString:@""];
if ([nstr isEqualToString:@"SuccessSuccess"])
{
// NSLog(@"可以上网了");
// [PronetwayGeneralHandle shareHandle].NetworkCanUse = YES;
return YES;
}else {
// NSLog(@"未联网");
//[self showNetworkStatus:@"未联网"];
// [PronetwayGeneralHandle shareHandle].NetworkCanUse = NO;
return NO;
}
}
//过滤后台返回字符串中的标签
+ (NSString *)flattenHTML:(NSString *)html {
NSScanner *theScanner;
NSString *text = nil;
theScanner = [NSScanner scannerWithString:html];
while ([theScanner isAtEnd] == NO) {
// find start of tag
[theScanner scanUpToString:@"<" intoString:NULL] ;
// find end of tag
[theScanner scanUpToString:@">" intoString:&text] ;
// replace the found tag with a space
//(you can filter multi-spaces out later if you wish)
html = [html stringByReplacingOccurrencesOfString:
[NSString stringWithFormat:@"%@>", text]
withString:@""];
}
return html;
}
这个网址是后台抓包抓到的,就是portal认证的原理是通过重定向页面来实现的,ios设备在连接wifi之后,会向这个网址发送一个请求,来检测联网状态..所以这个是苹果的地址 ,改变的可能性为0 其实也可以自己写个后台,弄一个外网地址,自己去请求,看返回结果,原理是一样的.
#define kAppleUrlTocheckWifi @"http://captive.apple.com"
好了 ,如此就解决了.另外,这个是同步请求,会阻塞线程的,所以请求的超时时间设置的不易过长!
最后推荐一个技术交流群,里面大神很多! 529043462