`

[IOS]如何判断网络状态

    博客分类:
  • IOS
阅读更多

1.先复制Reachability代码:

.h:

 

#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
#import <netinet/in.h>

typedef enum : NSInteger {
    NotReachable = 0,
    ReachableViaWiFi,
    ReachableViaWWAN
} NetworkStatus;

#pragma mark IPv6 协议支持
// Reachability完全支持IPv6协议.
extern NSString *kReachabilityChangedNotification;

@interface Reachability : NSObject
/*! * 用来检测hostName的连接状态. */
+ (instancetype)reachabilityWithHostName:(NSString *)hostName;
/*! * 用来检测IP地址的连接状态. */
+(instancetype)reachabilityWithAddress:(const struct sockaddr *)hostAddress;

/*! * 用来检测默认的连接是否可用, 被用在没有特定连接的主机. */
+ (instancetype)reachabilityForInternetConnection;

/*! *开始在当前时间循环中监听Reachability通知. */
- (BOOL)startNotifier; - (void)stopNotifier;
- (NetworkStatus)currentReachabilityStatus;

/*! * 除非连接已经建立,WWAN可用,但是却没有激活. WiFi 连结也许需要一个VPN来进行连接. */
- (BOOL)connectionRequired;

@end

 .m:

 

 

#import "Reachability.h"
#import <arpa/inet.h>
#import <ifaddrs.h>
#import <netdb.h>
#import <sys/socket.h>
#import <netinet/in.h>
#import <CoreFoundation/CoreFoundation.h>
#import "Reachability.h"
#pragma mark IPv6 协议支持
// Reachability完全支持IPv6协议.
NSString *kReachabilityChangedNotification = @"kNetworkReachabilityChangedNotification";
#pragma mark - 支持Reachability的方法
#define kShouldPrintReachabilityFlags 1
static void PrintReachabilityFlags(SCNetworkReachabilityFlags flags, const char* comment) {
#if kShouldPrintReachabilityFlags
    NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n",
          (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
          (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-',
          (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
          (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
          (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-',
          (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
          (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-',
          (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
          (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-', comment );
#endif
}

static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) {
#pragma 没有用的(target, flags)
    NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback");
    NSCAssert([(__bridge NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback");
    Reachability* noteObject = (__bridge Reachability *)info;
    // Post a notification to notify the client that the network reachability changed.
    [[NSNotificationCenter defaultCenter] postNotificationName: kReachabilityChangedNotification object: noteObject];
    
}

#pragma mark - Reachability的实现
@implementation Reachability

{
    SCNetworkReachabilityRef _reachabilityRef;
    
}

+ (instancetype)reachabilityWithHostName:(NSString *)hostName {
    Reachability* returnValue = NULL;
    SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
    if (reachability != NULL) {
        returnValue= [[self alloc] init];
        if (returnValue != NULL) { returnValue->_reachabilityRef = reachability;
            
        } else {
            CFRelease(reachability);
        }
    }
    return returnValue;
}

+ (instancetype)reachabilityWithAddress:(const struct sockaddr *)hostAddress {
    SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, hostAddress); Reachability* returnValue = NULL;
    if (reachability != NULL)
    { returnValue = [[self alloc] init];
        if (returnValue != NULL) {
            returnValue->_reachabilityRef = reachability;
        } else {
            CFRelease(reachability);
        }
    }
    return returnValue;
}

+ (instancetype)reachabilityForInternetConnection {
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress); zeroAddress.sin_family = AF_INET;
    return [self reachabilityWithAddress: (const struct sockaddr *) &zeroAddress];
}

#pragma mark - 开始和结束监听通知
- (BOOL)startNotifier { BOOL returnValue = NO;
    SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL};
    if (SCNetworkReachabilitySetCallback(_reachabilityRef, ReachabilityCallback, &context)){
        if (SCNetworkReachabilityScheduleWithRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)){
            returnValue = YES;
        }
    }
    return returnValue;
}

- (void)stopNotifier {
    if (_reachabilityRef != NULL) {
        SCNetworkReachabilityUnscheduleFromRunLoop(_reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    }
}

- (void)dealloc { [self stopNotifier]; if (_reachabilityRef != NULL) { CFRelease(_reachabilityRef); } }

#pragma mark - Network Flag Handling
- (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags {
    PrintReachabilityFlags(flags, "networkStatusForFlags");
    if ((flags & kSCNetworkReachabilityFlagsReachable) == 0){
        // The target host is not reachable.
        return NotReachable;
    }
    
    NetworkStatus returnValue = NotReachable;
    
    if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0) {
        /* If the target host is reachable and no connection is required then we'll assume (for now) that you're on Wi-Fi... */
        returnValue = 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... */
            returnValue = ReachableViaWiFi; }
        
    }
    
    if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN) {
        /* ... but WWAN connections are OK if the calling application is using the CFNetwork APIs. */
        returnValue = ReachableViaWWAN;
    }
    return returnValue;
}

- (BOOL)connectionRequired {
    NSAssert(_reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef"); SCNetworkReachabilityFlags flags;
    if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags)) {
        return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
        
    }
    return NO;
}

- (NetworkStatus)currentReachabilityStatus {
    NSAssert(_reachabilityRef != NULL, @"currentNetworkStatus called with NULL SCNetworkReachabilityRef");
    NetworkStatus returnValue = NotReachable; SCNetworkReachabilityFlags flags;
    if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags)){
        returnValue = [self networkStatusForFlags:flags];
    }
    return returnValue;
}

@end

 

 

2.使用:

#import "AppDelegate.h"
#import "Reachability.h"
@interface AppDelegate ()
//定义属性
@property(nonatomic,strong)Reachability *reachability;
@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    //创建通知
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(internetConnection) name:kReachabilityChangedNotification object:nil];

    //初始化可达性
    self.reachability =[Reachability reachabilityForInternetConnection];

    //开始监听
    [self.reachability startNotifier];
    [self internetConnection];
    return YES;
}

-(void)internetConnection
{   //网络连接现状
    NetworkStatus status =[self.reachability currentReachabilityStatus];
    switch (status) {
        case NotReachable:
            NSLog(@"没有网络");
            break;
        case ReachableViaWiFi:
            NSLog(@"wifi连接");
            break;
        case ReachableViaWWAN:
             NSLog(@"移动蜂窝网络");
            break;
        default:
            break;
    }

}

 可以放在Appdelegate中,作为全局使用。也可以放在需要检测网络连接状态的地方使用。 

 

参考:

1.https://blog.csdn.net/gezi0630/article/details/51934050

 

分享到:
评论

相关推荐

    iOS 判断网络状态

    在iOS开发中,判断设备的网络状态是一项基本且重要的任务,因为这直接影响到应用能否正常地获取和发送数据。这篇博客“iOS 判断网络状态”提供了实现这一功能的方法,通过查看其提供的源码文件“Reachability.h”和...

    iOS判断网络状态

    在iOS开发中,判断设备的网络状态是必不可少的一项功能,这可以帮助我们确保应用在恰当的时候加载数据或执行网络操作。本篇文章将详细讲解两种在iOS中判断网络状态的方法:通过系统StatusBar状态判断以及利用第三方...

    iOS 判断网络状态(包括2G,3G,4G)简单DEMO

    在iOS开发中,判断设备的网络状态是常见的需求,尤其对于需要实时数据交换的应用来说更为重要。本DEMO,"iOS 判断网络状态(包括2G,3G,4G)简单DEMO",提供了一个基于AFNetworking库的简单实现方案。AFNetworking是一...

    iOS 判断网络状态(包括2G,3G,4G)

    在iOS开发中,判断设备当前的网络状态是十分常见的需求,比如为了提供更好的用户体验,我们需要在用户连接到较慢的2G或3G网络时,调整应用的数据加载策略。本教程将详细介绍如何利用AFNetworking库来检测iOS设备的...

    iOS 网络状态判断demo

    "iOS 网络状态判断demo"就是一个展示如何在iOS应用中检测网络连接状况的示例项目。在这个项目中,主要涉及到的技术点包括系统提供的网络状态API、监听网络变化的方法以及在应用中实时反馈网络状态的策略。 首先,...

    iOS网络连接状态判断 JPNetwork

    "iOS网络连接状态判断 JPNetwork"是一个简单而实用的库,它帮助开发者轻松地检测iOS设备的网络连接状况。下面将详细阐述这个库的主要功能和实现原理。 首先,JPNetwork库主要由两个文件组成:JPNetwork.h和...

    swift-针对iOS网络权限的监控和判断

    综上所述,Swift中的网络权限监控和判断主要涉及到ATS配置、网络状态监听、用户隐私保护等方面。开发者应当充分了解这些知识点,确保应用的稳定性和安全性。通过合理使用Apple提供的工具和第三方库,我们可以构建出...

    iOS判断当前网络状态

    在iOS开发中,判断设备当前的网络状态是十分常见的需求,这有助于我们为用户提供最佳的网络体验。在本文中,我们将深入探讨如何在iOS中检测网络连接类型,包括2G、3G、4G以及Wi-Fi。我们将主要关注Objective-C和...

    ios监测网络状态

    在iOS开发中,监测网络状态是一项至关重要的任务,它能够帮助开发者实时了解用户设备的网络连通性,以便提供更好的用户体验。iOS系统提供了多种方法来检测网络状态,这些方法覆盖了从基本的网络连接检查到复杂的网络...

    ios-检测网络状态.zip

    在iOS开发中,检测网络状态是一项至关重要的任务,它能够帮助开发者及时了解用户设备的网络...在实际开发中,结合这些知识点,你可以创建一个健壮的网络状态检测机制,确保你的应用能够根据网络状况做出适当的反应。

    获取 ios 系统网络状况、电量

    综上所述,了解并使用`Reachability`库可以帮助我们监测iOS设备的网络状态,而通过`UIDevice`的电池状态和电量属性,我们可以获取电池相关信息。这些功能对于构建具有优秀用户体验的iOS应用来说非常重要。结合提供的...

    iOS 判断当前是否有网络

    在iOS开发中,确保应用程序能够实时检测和处理网络状态是一项重要的任务。用户可能在任何时间、任何地点使用应用,因此程序需要能够灵活地应对网络连接的变化。标题"iOS 判断当前是否有网络"以及描述"判断是否存在...

    Delphi跨平台(Win,Android,IOS)获取网络状态

    总的来说,通过这些文件,开发者可以构建一个跨平台的网络状态检测功能,使得Delphi应用能在Windows、Android和iOS上正确地判断网络连通性和类型,从而提升用户体验并优化应用的网络相关功能。在实际项目中,开发者...

    swift-iOS完美的网络状态判断工具

    Swift-iOS中的“完美的网络状态判断工具”主要是指利用Reachability框架来检测网络的可达性,确保应用能够及时响应网络状态的变化。这篇文档将深入探讨如何使用Reachability以及其在Swift开发中的应用。 首先, ...

    ios检查网络状态

    在iOS应用开发中,检查网络状态是至关重要的功能,它能确保用户在合适的网络环境下使用应用,避免因为网络问题导致的用户体验下降。本教程将基于标题"ios检查网络状态"和描述中的信息,深入讲解如何在iOS应用中实现...

    iOS 使用afnetworking封转的请求工具,上传 下载 判断网络状态

    本篇文章将深入探讨如何利用AFNetworking封装自己的请求工具,以及如何实现文件的上传下载和网络状态的判断。 首先,我们需要了解AFNetworking的基本用法。AFNetworking是由Alamofire团队开发的一个Objective-C框架...

    IOS网络连接状态检测

    "IOS网络连接状态检测"这一主题主要关注如何在iOS设备上检测应用所处的网络条件,如WiFi、2G、3G、4G等。这涉及到对网络状态的实时监控,以便在不同网络环境下提供最佳的用户体验。 首先,我们需要理解iOS提供的...

    iOS 获取网络类型

    在iOS开发中,通常使用`Reachability`框架来检测网络状态,它能够判断出设备是通过WiFi还是蜂窝数据连接的。如果你只需要了解是否连接到WiFi,可以利用`CaptiveNetwork`框架。然而,对于区分2G、3G、4G等具体网络...

    IOS网络播放器

    同时,为了处理网络状态变化和错误,你需要理解断点续传、网络状态监听和错误处理机制。 2. **数据解析**:获取到的数据可能以JSON、XML或自定义格式存在,需要解析成可操作的对象。对于JSON,可以使用系统的JSON...

    在ios工程中如何判断当前网络环境是IPV6还是IPV4 源码下载

    使用`SCNetworkReachabilityCreateWithName()`函数创建一个`SCNetworkReachabilityRef`对象,传入你的目标主机名或者“kSCNetworkReachabilityDefault”来检查默认的网络状态。 ```objc CFStringRef hostName = ...

Global site tag (gtag.js) - Google Analytics