iOS平台网络类型检测

老大新增个需求,连接服务器时要区分内外网,需求理解了,现实很骨感啊,没办法,干.

#import <Foundation/Foundation.h>
/*
 依赖于以下Framework
 SystemConfiguration
 CoreTelephony
 */
typedef enum _NetWorkType
{
    kNetworkOff = 0,
    kNetworkWifi,
    kNetworkWLan,//如果不能获取到更详细的,将统一返回该值(iOS7以上才能获取到)
    kNetworkWLan2G,
    kNetworkWLan3G,
    kNetworkGPRS,
    kNetworkEdge,
    kNetworkWCDMA,
    kNetworkHSDPA,
    kNetworkHSUPA,
    kNetworkCDMA1x,
    kNetworkCDMAEVDORev0,
    kNetworkCDMAEVDORevA,
    kNetworkCDMAEVDORevB,
    kNetworkHRPD,
    kNetworkLTE,
}NetworkType;
@interface HSNetworkDetect : NSObject

//通用接口
/*
 返回0~2的网络类型枚举值NetworkType
 */
+(NetworkType)getNetworkType;
/*
 iOS7及以上,确定是蜂窝网络的情况下,返回>2的网络类型枚举值;否则,仍返回2
 */
+(NetworkType)getCellularDataNetworkType;
/*
 检测网络是否可达,使用Reachability
 */
+(BOOL)isReachable:(NSString*)address port:(NSInteger)port;
/*
 获取当前连接的WIFI热点的SSID
 */
+(NSString*)getWifiSSID;

@end
#import "HSNetworkDetect.h"
#import "Reachability.h"
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <SystemConfiguration/CaptiveNetwork.h>

#define ISIOS7 !([[[UIDevice currentDevice] systemVersion] floatValue] <=6.9f)
#define SENTENCED_EMPTY(string)    (string = ((string == nil) ? @"":string))

@implementation HSNetworkDetect
#pragma mark 通用接口
+(NetworkType)getNetworkType
{
    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;
    SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
    if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
    {
        return kNetworkOff;
    }
    NetworkType retVal = kNetworkOff;
    if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
    {
        retVal = kNetworkWifi;
    }
    if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
         (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
    {
        if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
        {
            retVal = kNetworkWifi;
        }
    }

    if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
    {
        if((flags & kSCNetworkReachabilityFlagsReachable) == kSCNetworkReachabilityFlagsReachable) {
            if ((flags & kSCNetworkReachabilityFlagsTransientConnection) == kSCNetworkReachabilityFlagsTransientConnection)
            {
                retVal = kNetworkWLan3G;
                if((flags & kSCNetworkReachabilityFlagsConnectionRequired) == kSCNetworkReachabilityFlagsConnectionRequired)
                {
                    retVal = kNetworkWLan2G;
                }
            }
        }
    }
    return retVal;
}
+(NetworkType)getCellularDataNetworkType
{
    if (ISIOS7)
    {
        CTTelephonyNetworkInfo *telephonyInfo = [CTTelephonyNetworkInfo new];
        NSString* wlanNetwork = telephonyInfo.currentRadioAccessTechnology;
        if (wlanNetwork == nil)
            return kNetworkOff;
        if([wlanNetwork isEqualToString:CTRadioAccessTechnologyGPRS  		 ])
        {
            return kNetworkGPRS;
        }
        else if([wlanNetwork isEqualToString:CTRadioAccessTechnologyEdge        ])
        {
            return kNetworkEdge;
        }
        else if([wlanNetwork isEqualToString:CTRadioAccessTechnologyWCDMA       ])
        {
            return kNetworkWCDMA;
        }
        else if([wlanNetwork isEqualToString:CTRadioAccessTechnologyHSDPA       ])
        {
            return kNetworkHSDPA;
        }
        else if([wlanNetwork isEqualToString:CTRadioAccessTechnologyHSUPA       ])
        {
            return kNetworkHSUPA;
        }
        else if([wlanNetwork isEqualToString:CTRadioAccessTechnologyCDMA1x      ])
        {
            return kNetworkCDMA1x;
        }
        else if([wlanNetwork isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0])
        {
            return kNetworkCDMAEVDORev0;
        }
        else if([wlanNetwork isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA])
        {
            return kNetworkCDMAEVDORevA;
        }
        else if([wlanNetwork isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB])
        {
            return kNetworkCDMAEVDORevB;
        }
        else if([wlanNetwork isEqualToString:CTRadioAccessTechnologyeHRPD       ])
        {
            return kNetworkHRPD;
        }
        else if([wlanNetwork isEqualToString:CTRadioAccessTechnologyLTE         ])
        {
            return kNetworkLTE;
        }
    }
    return kNetworkWLan;
}
+(NSString*)getWifiSSID
{
    NSArray *ifs = (__bridge id)CNCopySupportedInterfaces();
    id info = nil;
    for (NSString *ifnam in ifs)
    {
        info = (__bridge id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
        if (info && [info count])
        {
            NSString *ssid=[info objectForKey:(__bridge NSString *)kCNNetworkInfoKeySSID];
            //NSString *bssid=[info objectForKey:(__bridge NSString *)kCNNetworkInfoKeyBSSID];
            //NSLog(@"interfaceName:%@ ssid:%@ bssid:%@",ifnam,ssid,bssid);
            return ssid;
        }
    }
    return nil;
}
+(BOOL)isReachable:(NSString*)address port:(NSInteger)port
{
    Reachability* poReach = [Reachability reachabilityWithHostname:[NSString stringWithFormat:@"%@:%d",address,port]];
    BOOL bRet = [poReach isReachable];
    return bRet;
}

@end

PS--->老大的脾气你别猜,猜来猜去你也猜不明白.
时间: 2024-08-03 09:18:03

iOS平台网络类型检测的相关文章

ios 获取网络类型

//获取网络类型 +(NSString *)getNetWorkStates{ UIApplication *app = [UIApplication sharedApplication]; NSArray *children = [[[app valueForKeyPath:@"statusBar"]valueForKeyPath:@"foregroundView"]subviews]; NSString *state = [[NSString alloc]ini

iOS获取网络类型的四种方法

Reachability类只能区分WIFI和WWAN类型,却无法区分2G网和3G网. 网上也有些方法,却都存在Bug. 经过网上查找资料和测试,基本上总结了以下几种方法: 1.使用导航栏的方式:(私有API) 代码: typedef enum { NetWorkType_None = 0, NetWorkType_WIFI, NetWorkType_2G, NetWorkType_3G, } NetWorkType; UIApplication *application = [UIApplica

iOS中使用 Reachability 检测网络区分手机网络类型 WiFi 和2 3 4 G

如果你想在iOS程序中提供一仅在wifi网络下使用(Reeder),或者在没有网络状态下提供离线模式(Evernote).那么你会使用到Reachability来实现网络检测. 写本文的目的 了解Reachability都能做什么 检测3中网络环境 2G/3G wifi 无网络 如何使用通知 单个controller 多个controller 简单的功能: 仅在wifi下使用 Reachability简介 Reachablity 是一个iOS下检测,iOS设备网络环境用的库. 监视目标网络是否可

iOS中使用 Reachability 检测网络

iOS中使用 Reachability 检测网络 内容提示:下提供离线模式(Evernote).那么你会使用到Reachability来实现网络检测.   写本文的目的 了解Reachability都能做什么 检测3中网络环境 2G/3G wifi 无网络 如何使用通知 单个controller 多个controller 简单的功能: 仅在wifi下使用 Reachability简介 Reachablity 是一个iOS下... 如果你想在iOS程序中提供一仅在wifi网络下使用(Reeder)

iOS网络-AFNetworking检测网络状态

可以使用AFN框架中的AFNetworkReachabilityManager来监听网络状态的改变,也可以利用苹果提供的Reachability来监听.建议在开发中直接使用AFN框架处理. 示例代码如下: -(void)afn { //1.创建网络状态监测管理者 AFNetworkReachabilityManager *manger = [AFNetworkReachabilityManager sharedManager]; //2.监听改变 [manger setReachabilityS

iOS使用Reachability实时检测网络连接状况

//在程序的启动处,开启通知 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //..... //开启网络状况的监听 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name: kR

【开发记录】iOS中使用 Reachability 检测网络

如果你想在iOS程序中提供一仅在wifi网络下使用(Reeder),或者在没有网络状态下提供离线模式(Evernote).那么你会使用到Reachability来实现网络检测. 写本文的目的 了解Reachability都能做什么 检测3中网络环境 2G/3G wifi 无网络 如何使用通知 单个controller 多个controller 简单的功能: 仅在wifi下使用 Reachability简介 Reachablity 是一个iOS下检测,iOS设备网络环境用的库. 监视目标网络是否可

Android检测网络是否可用并获取网络类型

在类中使用getSystemService的时候需要这样进行使用:1. public class JajaMenu extends Activity { public static JajaMenu instance; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.init(); instance=this; } //获取实例 public

ios获取手机状态 idfa &nbsp; idfv &nbsp; 网络类型 &nbsp; 分辨率 &nbsp; 获取运营商

//idfa [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]; //idfv [[[UIDevice currentDevice] identifierForVendor] UUIDString]; //网络类型 - (NSString *) getNet { UIApplication *application = [UIApplication sharedApplication]; NSArra