首页 > 代码库 > iOS 判断当前是否连接到网络和网络类型
iOS 判断当前是否连接到网络和网络类型
之前有判断过是否连接到网络,没有使用apple的示例中的Reachability。
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <SystemConfiguration/SCNetworkReachability.h>
-(BOOL)isConnectToNewtwork
{
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
SCNetworkReachabilityFlags flags;
BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
CFRelease(defaultRouteReachability);
if (!didRetrieveFlags) {
printf("Error. Count not recover network reachability flags\n");
return NO;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
return (isReachable && !needsConnection) ? YES : NO;
}
现在要判断网络的状态时,开始考虑用Reachability,http://www.cnblogs.com/mrhgw/archive/2012/08/01/2617760.html,这里有下载的连接,并且在http://bbs.9ria.com/thread-190107-1-1.html有提到重构,这样可以判断蜂窝数据使用的是3G还是2G。
//Reachability.m 中 networkStatusForFlags 方法重构- (NetworkStatus) networkStatusForFlags: (SCNetworkReachabilityFlags) flags{ if ((flags & kSCNetworkReachabilityFlagsReachable) == 0) { return NotReachable; } BOOL retVal = NotReachable; if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0) { // if target host is reachable and no connection is required // then we‘ll assume (for now) that your on Wi-Fi retVal = ReachableViaWiFi; } if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0)) { // ... and the connection is on-demand (or on-traffic) if the // calling application is using the CFSocketStream or higher APIs if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0) { // ... and no [user] intervention is needed retVal = ReachableViaWiFi; } } if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN) { if((flags & kSCNetworkReachabilityFlagsReachable) == kSCNetworkReachabilityFlagsReachable) { if ((flags & kSCNetworkReachabilityFlagsTransientConnection) == kSCNetworkReachabilityFlagsTransientConnection) { retVal = ReachableVia3G; if((flags & kSCNetworkReachabilityFlagsConnectionRequired) == kSCNetworkReachabilityFlagsConnectionRequired) { retVal = ReachableVia2G; } } } } return retVal;}//在需要用的地方实现以下2个方法//检查当前网络连接是否正常-(BOOL)connectedToNetWork{ struct sockaddr_in zeroAddress; bzero(&zeroAddress, sizeof(zeroAddress)); zeroAddress.sin_len = sizeof(zeroAddress); zeroAddress.sin_family = AF_INET; SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress); SCNetworkReachabilityFlags flags; BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags); CFRelease(defaultRouteReachability); if (!didRetrieveFlags) { printf("Error. Count not recover network reachability flags\n"); return NO; } BOOL isReachable = flags & kSCNetworkFlagsReachable; BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired; return (isReachable && !needsConnection) ? YES : NO;}//检查网络连接类型-(void)checkNetworktype:(id)sender{ NSString *connectionKind; if ([self connectedToNetWork]) { Reachability *hostReach = [Reachability reachabilityWithHostName:@"www.google.com"]; switch ([hostReach currentReachabilityStatus]) { case NotReachable: connectionKind = @"没有网络链接"; break; case ReachableViaWiFi: connectionKind = @"当前使用的网络类型是WIFI"; break; case ReachableVia3G: connectionKind = @"当前使用的网络链接类型是WWAN(3G)"; break; case ReachableVia2G: connectionKind = @"当前使用的网络链接类型是WWAN(2G)"; break; default: break; } }else { connectionKind = @"没有网络链接"; }}
虽然这样的方法可以判断,但是结果并不准确。
找到另外一种简单又准确的方法:
typedef enum { NETWORK_TYPE_NONE = 0, NETWORK_TYPE_2G = 1, NETWORK_TYPE_3G = 2, NETWORK_TYPE_4G = 3, NETWORK_TYPE_5G = 4,// 5G目前为猜测结果 NETWORK_TYPE_WIFI = 5}NETWORK_TYPE;-(NSString *)getNetworkType{ NSString *connectionKind; if ([self isConnectToNewtwork]) { UIApplication *app = [UIApplication sharedApplication]; NSArray *subviews = [[[app valueForKey:@"statusBar"] valueForKey:@"foregroundView"] subviews]; NSNumber *dataNetworkItemView = nil; for (id subview in subviews) { if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) { dataNetworkItemView = subview; break; } } NETWORK_TYPE nettype = NETWORK_TYPE_NONE; NSNumber * num = [dataNetworkItemView valueForKey:@"dataNetworkType"]; nettype = [num intValue]; switch ( nettype ) { case NETWORK_TYPE_NONE: connectionKind = @"没有网络链接"; break; case NETWORK_TYPE_WIFI: connectionKind = @"当前使用的网络类型是WIFI"; break; case NETWORK_TYPE_4G: connectionKind = @"当前使用的网络链接类型是WWAN(4G)"; break; case NETWORK_TYPE_3G: connectionKind = @"当前使用的网络链接类型是WWAN(3G)"; break; case NETWORK_TYPE_2G: connectionKind = @"当前使用的网络链接类型是WWAN(2G)"; break; default: break; } }else { connectionKind = @"没有网络链接"; } return connectionKind;}
iOS 判断当前是否连接到网络和网络类型