ios-Research Afnetworking (1)-afnetworkreachabilitymanager class

Source: Internet
Author: User

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 ...

















































Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.