The Afnetworkreachabilitymanager class is provided in afnetworking to apply the monitoring of network state in the lifecycle.
Afnetworkreachabilitymanager inherits from NSObject
@interface Afnetworkreachabilitymanager:nsobject
Afnetworkreachabilitymanager defines an enumeration that is designed to represent the various states of a network
typedef ns_enum (Nsinteger, afnetworkreachabilitystatus) {
Afnetworkreachabilitystatusunknown =-1,
Afnetworkreachabilitystatusnotreachable = 0,
Afnetworkreachabilitystatusreachableviawwan = 1,
Afnetworkreachabilitystatusreachableviawifi = 2,
};
Afnetworkreachabilitystatusunknown indicates an unknown network
Afnetworkreachabilitystatusnotreachable indicates that the network is not connected
Afnetworkreachabilitystatusreachableviawwan says it's a mobile network, 2g,3g,4g.
Afnetworkreachabilitystatusreachableviawifi indicates a connected WiFi
@property (readonly, nonatomic, assign) Afnetworkreachabilitystatus networkreachabilitystatus;
The Networkreachabilitystatus property represents the network status of the current application
@property (readonly, nonatomic, assign, getter = isreachable) BOOL reachable;
The Reachable property indicates whether the current application is connected to the network, the getter method for this property is redefined, and if the application is in the mobile phone network (WWAN) or WiFi state, return yes, otherwise return no, as follows
-(BOOL) isreachable {return
[self Isreachableviawwan] | | [Self Isreachableviawifi];
}
@property (readonly, nonatomic, assign, getter = Isreachableviawwan) BOOL Reachableviawwan;
The Reachableviawwan property indicates whether the application is currently in the Wwan network state and returns YES if it is in the network environment, otherwise returns no
@property (readonly, nonatomic, assign, getter = Isreachableviawifi) BOOL Reachableviawifi;
The Reachableviawifi property indicates whether the application is currently in a WiFi network state, returns YES if the application is in a WiFi environment, or returns no
The property is here, and we're going to look at it in the. m file.
--------------------------------------------------------------------Split Line, Bang Bang--------------------------------------------------------------------------------
@interface Afnetworkreachabilitymanager ()
@property (readonly, nonatomic, assign) scnetworkreachabilityref networkreachability;
@property (ReadWrite, nonatomic, assign) Afnetworkreachabilitystatus networkreachabilitystatus;
@property (ReadWrite, nonatomic, copy) Afnetworkreachabilitystatusblock Networkreachabilitystatusblock;
@end
Scnetworkreachabilityref networkreachability; Property
Afnetworkreachabilitystatus Networkreachabilitystatus; Property
Afnetworkreachabilitystatusblock Networkreachabilitystatusblock; property, which is a block property that is used to make a network state connection, and callback the block
+ (Instancetype) Manager
{
#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];
}
To analyze the next + (Instancetype) Manager class method:
Precompiled first, based on __iphone_os_version_min_required (iOS version number) above 9.0, and __mac_os_x_version_min_required (MAC version number) above 10.11, then we have to use the IPv6 method, if less than the version number of the two systems, we use the IPv4 approach to create socket sockets.
+ (Instancetype) managerforaddress: (const void *) address {
Scnetworkreachabilityref reachability = Scnetworkreachabilitycreatewithaddress (Kcfallocatordefault, (const struct SOCKADDR *) address);
Afnetworkreachabilitymanager *manager = [[Self alloc] initwithreachability:reachability];
Cfrelease (reachability);
return manager;
}
Managerforaddress This class method is to create a network connection reference based on the incoming socket.
Scnetworkreachabilityref reachability = scnetworkreachabilitycreatewithaddress (kcfallocatordefault, const struct SOCKADDR *) address);
The C method is to obtain a reference to the network connection based on the parameters passed in, the first parameter can be null or Kcfallocatordefault, and the second parameter is the IP address that needs to test the connection. Create a network connection reference scnetworkreachabilityref after use, be aware of using Cfrelease to release this data
The above refers to the use of sockets as a network connection reference to create the parameters, the same, we can not use the socket IP address to do parameters, we can provide a domain name to create a network connection reference
+ (Instancetype) Managerfordomain: (NSString *) domain {
scnetworkreachabilityref reachability = Scnetworkreachabilitycreatewithname (Kcfallocatordefault, [domain utf8string]);
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;
}
Once we have a reference to the Scnetworkreachabilityref network connection, we can use this connection reference to initialize our attribute _networkreachability, and in the initialization we will first Self.networkreachabilitystatus is set to an unknown network state.
+ (Instancetype) Sharedmanager {
static afnetworkreachabilitymanager *_sharedmanager = nil;
Static dispatch_once_t Oncetoken;
Dispatch_once (&oncetoken, ^{
_sharedmanager = [self manager];
});
return _sharedmanager;
}
The Sharedmanager method is to use the manager to get the Afnetworkreachabilitymanager single case
-(void) Dealloc {
[self stopmonitoring];
if (_networkreachability!= NULL) {
cfrelease (_networkreachability);
}
}
destructor, the operation inside must release the resources.
-(BOOL) isreachable {return
[self Isreachableviawwan] | | [Self Isreachableviawifi];
}
-(BOOL) Isreachableviawwan {return
self.networkreachabilitystatus = = Afnetworkreachabilitystatusreachableviawwan;
}
-(BOOL) Isreachableviawifi {return
self.networkreachabilitystatus = = Afnetworkreachabilitystatusreachableviawifi;
}
Returns a property that determines where the application is in the network state
-(void) startmonitoring {[Self stopmonitoring];
if (!self.networkreachability) {return;
} __weak __typeof (self) weakself = self; Afnetworkreachabilitystatusblock callback = ^ (Afnetworkreachabilitystatus status) {__strong __typeof (weakSelf) str
Ongself = 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), ^{SCNetworkReachabilityFlagsFlags if (Scnetworkreachabilitygetflags (self.networkreachability, &flags)) {Afpostreachabilitystatuschange (flag
S, callback);
}
}); }
Let's focus on the implementation of this approach:
__weak __typeof (self) weakself = self;
Afnetworkreachabilitystatusblock callback = ^ (Afnetworkreachabilitystatus status) {
__strong __typeof (weakSelf) Strongself = weakself;
Strongself.networkreachabilitystatus = status;
if (strongself.networkreachabilitystatusblock) {
strongself.networkreachabilitystatusblock (status);
}
;
Here we create a Afnetworkreachabilitystatusblock type block, in which we execute our property block, which means that once the callback callback the block, Then the corresponding properties of our custom Afnetworkreachabilitystatusblock _networkreachabilitystatusblock will also be recalled.
Scnetworkreachabilitycontext context = {0, (__bridge void *) callback, Afnetworkreachabilityretaincallback, Afnetworkreachabilityreleasecallback, NULL};
Create Scnetworkreachabilitycontext context to introduce the content of Scnetworkreachabilitycontext structure
typedef struct {
Cfindex version;
void * INFO;
const void * (*retain) (const void *info);
void (*release) (const void *info);
Cfstringref (*copydescription) (const void *info);
Scnetworkreachabilitycontext;
Some of the parameters involved in this structure
Cfindex version; 0
void * INFO; Is the callback created above
const void * (*retain) (const void * info); Returns any pointer type, the parameter is a pointer, the pointer function
static const void * Afnetworkreachabilityretaincallback (const void *info) {return
block_copy (info);
}
void (*release) (const void * info);
static void Afnetworkreachabilityreleasecallback (const void *info) {
if (info) {
block_release (info);
}
}
Cfstringref (*copydescription) (const void *info); Null
Scnetworkreachabilitysetcallback (self.networkreachability, Afnetworkreachabilitycallback, &context);
Try to set a callback method for self.networkreachability This network connection reference, and if self.networkreachability This network connection reference changes, then Afnetworkreachabilitycallback will recall
static void Afnetworkreachabilitycallback (Scnetworkreachabilityref __unused target, scnetworkreachabilityflags flags , void *info) {
Afpostreachabilitystatuschange (flags, (__bridge afnetworkreachabilitystatusblock) info);
}
Once the self.networkreachability has changed, the top method is called, so Afpostreachabilitystatuschange () is invoked.
static void Afpostreachabilitystatuschange (Scnetworkreachabilityflags flags, afnetworkreachabilitystatusblock block ) {
Afnetworkreachabilitystatus status = Afnetworkreachabilitystatusforflags (flags);
Dispatch_async (Dispatch_get_main_queue (), ^{
if (block) {block
(status);
}
Nsnotificationcenter *notificationcenter = [Nsnotificationcenter defaultcenter];
Nsdictionary *userinfo = @{Afnetworkingreachabilitynotificationstatusitem: @ (status)};
[Notificationcenter postnotificationname:afnetworkingreachabilitydidchangenotification Object:nil UserInfo: UserInfo];}
Then the network connection status is obtained according to the flags Afnetworkreachabilitystatus
Static Afnetworkreachabilitystatus Afnetworkreachabilitystatusforflags (Scnetworkreachabilityflags flags) {BOOL
Isreachable = ((Flags & kscnetworkreachabilityflagsreachable)!= 0);
BOOL needsconnection = ((Flags & kscnetworkreachabilityflagsconnectionrequired)!= 0); BOOL canconnectionautomatically = ((Flags & Kscnetworkreachabilityflagsconnectionondemand)!= 0) | |
((Flags & Kscnetworkreachabilityflagsconnectionontraffic)!= 0)); BOOL canconnectwithoutuserinteraction = (canconnectionautomatically && (Flags &
kscnetworkreachabilityflagsinterventionrequired) = = 0);
BOOL isnetworkreachable = (isreachable && (!needsconnection | | canconnectwithoutuserinteraction));
Afnetworkreachabilitystatus status = Afnetworkreachabilitystatusunknown;
if (isnetworkreachable = NO) {status = Afnetworkreachabilitystatusnotreachable;
#if Target_os_iphone Else if ((Flags & Kscnetworkreachabilityflagsiswwan)!= 0) { status = Afnetworkreachabilitystatusreachableviawwan;
#endif else {status = Afnetworkreachabilitystatusreachableviawifi;
} return status; }
Then asynchronously executes the callback callback method, and the natural our Custom block attribute is also invoked, which is explained above.
Finally send the afnetworkingreachabilitydidchangenotification notification, this notice carries the network status situation
Scnetworkreachabilityschedulewithrunloop (Self.networkreachability, Cfrunloopgetmain (), kCFRunLoopCommonModes);
This code is to put the network connection reference state changes in the Mainrunloop, in order to be in the application of the entire lifecycle, can be detected and response.
Dispatch_async (Dispatch_get_global_queue (dispatch_queue_priority_background, 0), ^{
Scnetworkreachabilityflags flags;
if (Scnetworkreachabilitygetflags (self.networkreachability, &flags)) {
Afpostreachabilitystatuschange ( Flags, callback);
}
);
Boolean scnetworkreachabilitygetflags ( scnetworkreachabilityref target, scnetworkreachabilit Yflags *flags ); This function is used to obtain the state of the test connection, the first parameter is a reference to the previously established test connection, the second parameter is used to save the obtained state, and returns True if the state is obtained, or false
To asynchronously perform a monitoring of whether a network connection reference state has changed
-(void) stopmonitoring {
if (!self.networkreachability) {return
;
}
Scnetworkreachabilityunschedulefromrunloop (Self.networkreachability, Cfrunloopgetmain (), kCFRunLoopCommonModes);
Stop listening for network connection reference state, remove from Mainrunloop
-(void) Setreachabilitystatuschangeblock: (void (^) (afnetworkreachabilitystatus status)) block {
Self.networkreachabilitystatusblock = Block;
}
customizing our block content, giving Self.networkreachabilitystatusblock what we want to do to meet the needs of the project
About the analysis of Afnetworkreachabilitymanager here, later encountered practical applications, and then come back to supplement the actual use of ...