首页 > 代码库 > 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 判断当前是否连接到网络和网络类型