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

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。