AFNetworkReachabilityManager
這個(gè)類主要是監(jiān)聽當(dāng)前的網(wǎng)絡(luò)狀態(tài),并通過(guò)通知廣播給調(diào)用者。
網(wǎng)絡(luò)狀態(tài)有如下幾種,分別對(duì)應(yīng)的未知、斷網(wǎng)、移動(dòng)網(wǎng)絡(luò)、Wi-Fi
typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
AFNetworkReachabilityStatusUnknown = -1,
AFNetworkReachabilityStatusNotReachable = 0,
AFNetworkReachabilityStatusReachableViaWWAN = 1,
AFNetworkReachabilityStatusReachableViaWiFi = 2,
};
官方已經(jīng)提供一個(gè)句柄來(lái)標(biāo)識(shí)網(wǎng)絡(luò)地址狀態(tài),就是它”SCNetworkReachabilityRef”,先看看AFNetworkReachabilityManager其中幾個(gè)初始化方法。
- 第一個(gè)方法使用domain參數(shù)來(lái)初始化一個(gè)實(shí)例,同理第二個(gè)方法使用address來(lái)初始化實(shí)例。這里需要注意,如果使用非Cocoa框架的類創(chuàng)建一個(gè)實(shí)例,需要手動(dòng)對(duì)這個(gè)對(duì)象進(jìn)行內(nèi)存管理。
- 第四個(gè)方法是作者推薦用的初始化方法,根據(jù)當(dāng)前iOS開發(fā)最低支持編譯版本是否大于9.0來(lái)創(chuàng)建對(duì)應(yīng)的網(wǎng)絡(luò)協(xié)議對(duì)象,大于9.0則創(chuàng)建IPv6,否則創(chuàng)建IPv4
+ (instancetype)managerForDomain:(NSString *)domain {
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [domain UTF8String]);
AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability];
CFRelease(reachability);
return manager;
}
+ (instancetype)managerForAddress:(const void *)address {
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address);
AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability];
CFRelease(reachability);
return manager;
}
- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability {
self = [super init];
if (!self) {
return nil;
}
_networkReachability = CFRetain(reachability);
self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown;
return self;
}
+ (instancetype)manager {
// __IPHONE_OS_VERSION_MIN_REQUIRED 表示當(dāng)前開發(fā)環(huán)境最低支持的版本號(hào)
// 編譯時(shí)判斷如果當(dāng)前iOS開發(fā)環(huán)境版本低于9.0則使用IPv4,否則使用IPv6的結(jié)構(gòu)體
#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)
struct sockaddr_in6 address;
bzero(&address, sizeof(address));
address.sin6_len = sizeof(address);
address.sin6_family = AF_INET6;
#else
struct sockaddr_in address;
bzero(&address, sizeof(address));
address.sin_len = sizeof(address);
address.sin_family = AF_INET;
#endif
return [self managerForAddress:&address];
}
- 開啟監(jiān)聽
- (void)startMonitoring {
[self stopMonitoring];
if (!self.networkReachability) {
return;
}
// 設(shè)置網(wǎng)絡(luò)狀態(tài)監(jiān)聽回調(diào)
__weak __typeof(self)weakSelf = self;
AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
strongSelf.networkReachabilityStatus = status;
if (strongSelf.networkReachabilityStatusBlock) {
strongSelf.networkReachabilityStatusBlock(status);
}
};
SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL};
SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context);
SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
SCNetworkReachabilityFlags flags;
if (SCNetworkReachabilityGetFlags(self.networkReachability, &flags)) {
AFPostReachabilityStatusChange(flags, callback);
}
});
}
- 關(guān)閉監(jiān)聽
- (void)stopMonitoring {
if (!self.networkReachability) {
return;
}
SCNetworkReachabilityUnscheduleFromRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
}