iOS 判斷當前是否鏈接到網絡和網絡類型

以前有判斷過是否鏈接到網絡,沒有使用apple的示例中的Reachability。html

#import <sys/socket.h>網絡

#import <netinet/in.h>app

#import <arpa/inet.h>socket

#import <SystemConfiguration/SCNetworkReachability.h>ui

-(BOOL)isConnectToNewtworkgoogle

{netty

    struct sockaddr_in zeroAddress;htm

    bzero(&zeroAddress, sizeof(zeroAddress));blog

    zeroAddress.sin_len = sizeof(zeroAddress);get

    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;
}
相關文章
相關標籤/搜索