之前有判断过是否连接到网络,没有使用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;
}