[IOS] How to judge the network status

1. Copy the Reachability code first:

.h:

 

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

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

#pragma mark IPv6 protocol support
// Reachability fully supports IPv6 protocol.
extern NSString *kReachabilityChangedNotification;

@interface Reachability : NSObject
/*! * Used to detect the connection status of hostName. */
+ (instancetype)reachabilityWithHostName:(NSString *)hostName;
/*! * Used to detect the connection status of the IP address. */
+(instancetype)reachabilityWithAddress:(const struct sockaddr *)hostAddress;

/*! * Used to check if the default connection is available, used on hosts that do not have a specific connection. */
+ (instancetype)reachabilityForInternetConnection;

/*! *Start listening for Reachability notifications in the current time loop. */
- (BOOL)startNotifier; - (void)stopNotifier;
- (NetworkStatus)currentReachabilityStatus;

/*! * WWAN is available but not active unless the connection is established. WiFi connections may require a VPN to connect. */
- (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 protocol support
// Reachability fully supports IPv6 protocol.
NSString *kReachabilityChangedNotification = @"kNetworkReachabilityChangedNotification";
#pragma mark - Methods to support 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 useless (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 - Implementation of 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 - start and end listening notifications
- (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. Use:

#import "AppDelegate.h"
#import "Reachability.h"
@interface AppDelegate ()
//define properties
@property(nonatomic,strong)Reachability *reachability;
@end

@implementation AppDelegate


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

    //create notification
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(internetConnection) name:kReachabilityChangedNotification object:nil];

    //initialize reachability
    self.reachability =[Reachability reachabilityForInternetConnection];

    // start listening
    [self.reachability startNotifier];
    [self internetConnection];
    return YES;
}

-(void)internetConnection
{ //Network connection status
    NetworkStatus status =[self.reachability currentReachabilityStatus];
    switch (status) {
        case NotReachable:
            NSLog(@"No network");
            break;
        case ReachableViaWiFi:
            NSLog(@"wifi connection");
            break;
        case ReachableViaWWAN:
             NSLog(@"Mobile Cellular");
            break;
        default:
            break;
    }

}

 Can be placed in Appdelegate for global use. It can also be used where it is necessary to detect the status of the network connection. 

 

refer to:

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

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326004929&siteId=291194637