• app启动监听网络类型


    1、首先导入一个公共类Reachability.h文件:

    #import <Foundation/Foundation.h>
    #import <SystemConfiguration/SystemConfiguration.h>
    #import <netinet/in.h>
    
    
    typedef enum : NSInteger {
        NotReachable = 0,
        ReachableViaWiFi,
        ReachableViaWWAN
    } NetworkStatus;
    
    
    extern NSString *kReachabilityChangedNotification;
    
    
    @interface Reachability : NSObject
    
    /*!
     * Use to check the reachability of a given host name.
     */
    + (instancetype)reachabilityWithHostName:(NSString *)hostName;
    
    /*!
     * Use to check the reachability of a given IP address.
     */
    + (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress;
    
    /*!
     * Checks whether the default route is available. Should be used by applications that do not connect to a particular host.
     */
    + (instancetype)reachabilityForInternetConnection;
    
    /*!
     * Checks whether a local WiFi connection is available.
     */
    + (instancetype)reachabilityForLocalWiFi;
    
    /*!
     * Start listening for reachability notifications on the current run loop.
     */
    - (BOOL)startNotifier;
    - (void)stopNotifier;
    
    - (NetworkStatus)currentReachabilityStatus;
    
    /*!
     * WWAN may be available, but not active until a connection has been established. WiFi may require a connection for VPN on Demand.
     */
    - (BOOL)connectionRequired;
    
    @end

    Reachability.m 文件:

    #import <arpa/inet.h>
    #import <ifaddrs.h>
    #import <netdb.h>
    #import <sys/socket.h>
    
    #import <CoreFoundation/CoreFoundation.h>
    
    #import "Reachability.h"
    
    
    NSString *kReachabilityChangedNotification = @"kNetworkReachabilityChangedNotification";
    
    
    #pragma mark - Supporting functions
    
    #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
    ",
              (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 unused (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
    
    @implementation Reachability
    {
        BOOL _alwaysReturnLocalWiFiStatus; //default is NO
        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;
                returnValue->_alwaysReturnLocalWiFiStatus = NO;
            }
        }
        return returnValue;
    }
    
    
    + (instancetype)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress
    {
        SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)hostAddress);
    
        Reachability* returnValue = NULL;
    
        if (reachability != NULL)
        {
            returnValue = [[self alloc] init];
            if (returnValue != NULL)
            {
                returnValue->_reachabilityRef = reachability;
                returnValue->_alwaysReturnLocalWiFiStatus = NO;
            }
        }
        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:&zeroAddress];
    }
    
    
    + (instancetype)reachabilityForLocalWiFi
    {
        struct sockaddr_in localWifiAddress;
        bzero(&localWifiAddress, sizeof(localWifiAddress));
        localWifiAddress.sin_len = sizeof(localWifiAddress);
        localWifiAddress.sin_family = AF_INET;
    
        // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0.
        localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
    
        Reachability* returnValue = [self reachabilityWithAddress: &localWifiAddress];
        if (returnValue != NULL)
        {
            returnValue->_alwaysReturnLocalWiFiStatus = YES;
        }
        
        return returnValue;
    }
    
    
    #pragma mark - Start and stop notifier
    
    - (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)localWiFiStatusForFlags:(SCNetworkReachabilityFlags)flags
    {
        PrintReachabilityFlags(flags, "localWiFiStatusForFlags");
        NetworkStatus returnValue = NotReachable;
    
        if ((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect))
        {
            returnValue = ReachableViaWiFi;
        }
        
        return returnValue;
    }
    
    
    - (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))
        {
            if (_alwaysReturnLocalWiFiStatus)
            {
                returnValue = [self localWiFiStatusForFlags:flags];
            }
            else
            {
                returnValue = [self networkStatusForFlags:flags];
            }
        }
        
        return returnValue;
    }
    
    
    @end

    2、开启网络监听,注册通知

    // 开启网络状况的监听
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(reachabilityChanged:)
                                                     name:kReachabilityChangedNotification
                                                   object:nil
         ];
        self.reachability = [Reachability reachabilityWithHostName:@"www.baidu.com"];
        [self.reachability startNotifier];

    3、监听到通知,作相应的操作

    - (void)reachabilityChanged:(NSNotification* )note
    {
        Reachability *curReach  = [note object];
        NetworkStatus status    = [curReach currentReachabilityStatus];
        
        NSLog(@"网络状态值: %ld", (long)status);
        
        // 根据网络状态值,在这里做你想做的事
        // ...
    }
  • 相关阅读:
    Golang关键字—— var
    Ubuntu下搭建Golang开发环境
    CentOS安装MongoDB
    使用2-3法则设计分布式数据访问层
    8 种提升 ASP.NET Web API 性能的方法
    MongoDB 聚合之 MapReduce
    常用开源项目及工具汇总——持续更新
    了解一下jsp
    前苹果副总裁:如果你做的事情毫不费力,就是在浪费时间
    思考
  • 原文地址:https://www.cnblogs.com/angongIT/p/5333085.html
Copyright © 2020-2023  润新知