iOS development, afnetworking This network framework must be very familiar with, perhaps we usually only use its part of the function, and our implementation of the principle is not very clear, as if there is always a fog in front of the same.
Next we will read the code of this framework in great detail, our goal is to understand its ideas, to understand how our requests are implemented, where our code needs to be improved, if we can go further, we can summarize a set of network architecture for most of the application ideas.
Can help some people benefit from it.
Let's take a look at the entire framework of the file system, we do not explain the role of each file, in the entire source interpretation of the final article we will summarize the entire framework. There will be a clear chart to illustrate the problem.
When we look at a frame, we can look at it first, look at the header file of each file, the. h file
As you can see, some header files contain other header files, without considering the system's header file, we can find some relatively independent classes, from which we could see
The more independent classes are:
1.afurlresponseserialization.h
2.afnetworkreachabilitymanager.h
3.afurlrequestserialization.h
4.afsecuritypolicy.h
This article introduces the content of AFNetworkReachabilityManager.h, which is a class used to monitor changes in the network environment.
#import <SystemConfiguration/SystemConfiguration.h>
By importing this header file, we learned that the implementation of network monitoring relies on the SystemConfiguration API. It shows that this API can provide such a function, at least let us understand that we will usually import it for one purpose.
Whether this is an enumeration wrapper or a principle that uses enumerations, we consider enumerations when we meet a limited set of unified themes. Here the author has enumerated 4 types. These types can meet most of the features of our development, and if not, you can extend them yourself.
Ns_assume_nonnull_beginns_assume_nonnull_end
This is added for Swift's optional type, and the parameters for the content at both endpoints are nonnull by default.
This text is a description of this class. We don't care what it says, look at Apple's official
Such content will appear above a property or method, with the purpose of interpreting its contents. I see here think of our usual development, we can take each piece of code as the development of the API, but also write the comments in detail. Have seen two different kinds of rhetoric, one is to say the code comments as little as possible, requiring code introduction readability. Another is to say that the comments are detailed, focusing on how others feel about reading the code. Personal feeling or writing a little more good, because it may be a while later, you can go to see their own writing code may not remember. It is possible to think of something in the process of writing these tedious comments, such as how to merge some unnecessary methods and so on.
This class provides four read-only properties to let us get the content we need
1. Network Status
2. Is it possible to reach the
3. Whether the current connection is Wwan
4. The current connection is enough WiFi
All four properties are read-only, giving the user access rights, and note that the bool attribute is generally written to the Getter method.
The author uses this to separate the different function modules in the same class. This is a person's habit problem. For example, in the. m file I personally use #pragma mark to separate different functions.
5 initialization methods are available to meet most of the requirements.
Scnetworkreachabilityref This is very important, and this class is based on its development.
+ (instancetype) Managerfordomain: (nsstring *) domain; monitor the network status of the domain.
+ (instancetype) managerforaddress: (const void *) address; Listen for the network status of a socket Socket communication See this article: Socket communication
Turn on and off the listening method.
A string that returns the local language of a network state. Often we can tell the user based on this string, what is happening in the current network, of course, you can also customize the hint text according to the state.
To set a callback for network change, there are two ways to listen for network-changed callbacks:
1. Use this method on the top.
2. Monitor afnetworkingreachabilitydidchangenotification notifications.
This is a notification related to network status changes. The accepted notification will have a userinfo is a nsdictionary where key is
Afnetworkingreachabilitynotificationstatusitem
This simple two lines of code can tell us that in our usual development in the design to the notification function, we should be the notification of the string encapsulated in a proprietary file, while within the file by different modules to distinguish, of course, necessary comments are necessary.
PS: both Foundation_export and # define can define constants. Foundation_export can use = = to judge, the efficiency is slightly higher. And be able to hide the definition details (that is, the implementation part is not.)
Pair function: Gets the string declaration based on the state.
Well, the. h file of this class we have been very convinced to read, we are not about to say what he provides, but by reading each line of code, we can associate what, what can help us better programming.
Let's keep looking at the contents of AFNETWORKREACHABILITYMANAGER.M.
These header files are system libraries, are prepared for the sockaddr_in6/ sockaddr_in behind, unfamiliar can read this article socket communication
There's nothing left to say, let's keep looking.
This method is the implementation of the last method in. h. Our attention is nslocalizedstringfromtable this macro. Why pay attention to it?
This involves the problem of local internationalization. The so-called internationalization is to allow your app to display the corresponding language in different languages.
But this is not easy, inexperienced developers, may not be in the beginning to do such a setup, if you need international words later, in doing is very troublesome. So in the open, whenever the use of strings to the place to consider language differences. In different languages, the length of the string used for the expression of a meaning is not the same, which implies that the width of the space may vary.
Well, the internationalization of the content will not be said, please search by yourself.
1/** 2 * According to Scnetworkreachabilityflags, this network tag is converted to the network state we use frequently in development 3 1. Unable to connect to Network 4 2. Cellular Connection 5 3.WiFi connection 6 4. Unknown Connection 7 */8 static afnetworkreachabilitystatus Afnetworkreachabilitystatusforflags (Scnetworkreachabilityflags flags) { 9 10//can reach one-BOOL isreachable = ((Flags & kscnetworkreachabilityflagsreachable)! = 0); 12 13// You need to establish a connection before you connect. BOOL needsconnection = ((Flags & kscnetworkreachabilityflagsconnectionrequired)! = 0); 15 16 Whether it is possible to automatically connect the canconnectionautomatically = ((Flags & kscnetworkreachabilityflagsconnectionondemand)! = 0) || ((Flags & kscnetworkreachabilityflagsconnectionontraffic)! = 0)); 18 19//Can be connected, without the user manually set the premise of the Canconnectwithoutuserinteraction = (canconnectionautomatically && ; (Flags & kscnetworkreachabilityflagsinterventionrequired) = = 0); 21 22//Can be connected to the condition 1. able to reach 2. No need to establish a connection or do not require user manual setup The connection represents the ability to connect to a network of isnetworkreachable = (isreachable && (!needsconnection | | canconnectwithoutuserinteraction)); Afnetworkreachabilitystatus status = Afnetworkreachabilitystatusunknown;26 if (isnetworkreachable = = NO) {status = afnetworkreachabilitystatusnotreachable;28}29 #if target_os_ IPHONE30 else if (Flags & Kscnetworkreachabilityflagsiswwan)! = 0) {status = Afnetworkreachabilitystat Usreachableviawwan;32}33 #endif34 Else {status = afnetworkreachabilitystatusreachableviawifi;36}3 7. Return status;39}
This method is converted to our custom enumeration type based on the scnetworkreachabilityflags tag. As for the conversion rules, the comments section of the above code is clearly written.
I have to say a few more words here, and many of the frameworks will write private methods in a class like this. Why is it? We often write in development-(void) funcName; Such a private method.
My personal opinion is that a private method in a class is better written as a C function such as static void FuncName ().
1. At the front of the file, it's easier to find
2. You can use inline functions appropriately to improve efficiency.
Block and notifications are handled according to an identity. Ensure that both are in the same state.
Contains the properties that need to be handled in the class.
To see the most basic initialization method, initialize its own properties.
Cfretain () to remember Cfrelease ().
Initialized with a socket address. First create a new Scnetworkreachabilityref object, and then call the initwithreachability: method. Remember to manage memory manually.
This method is basically ibid.
Combining the top two methods, we found that Scnetworkreachabilityref has two methods of creation:
1. Scnetworkreachabilitycreatewithname
2. scnetworkreachabilitycreatewithaddress
Since IPV6 is iOS9 and os_x 10.11 behind the launch, all to be version judged. This week. Design to the socket of knowledge, see socket communication
What can we learn from this code?
1, the creation of methods is also sequential, you can use functions to access the idea of the function.
2. @if such a precompiled instruction can replace some of the if else in the code. The advantage is that the code will not be compiled differently.
A single example of the wording.
Do some processing when you need to release.
This is the getter method for the 3 bool attributes exposed by the. h file, note that because we define getter methods in @property, the Getter method is written as we define it.
From these 3 methods can also be seen, the idea of nested function is still very important, to achieve this, can only be a lot of thinking.
This is the core method of this class, set up listening network monitoring.
Let's start by understanding the basics.
Scnetworkreachabilitycontext
Point in, you will find this is a struct, general C language structure is a description of the data to be saved
1. The first parameter accepts a signed long argument
2. The second parameter accepts a value of type void *, equivalent to the ID type of OC, and void * can point to any type of argument
3. The third parameter is a function that is intended to do a retain operation on info.
4. The fourth parameter is a function that is intended to be a release operation for info
5. The fifth parameter is a function that gets the description string based on info
The info we're going to carry here is the block below.
1 __weak __typeof (self) weakself = self; 2 Afnetworkreachabilitystatusblock callback = ^ (Afnetworkreachabilitystatus status) {3 __strong __typeof ( weakself) strongself = weakself; 4 5 strongself.networkreachabilitystatus = status; 6 if (strongself.networkreachabilitystatusblock) {7 strongself.networkreachabilitystatusblock (status); 8 } 9 };
The retain and release functions are the two functions below
1 static const void * Afnetworkreachabilityretaincallback (const void *info) {2 return block_copy (info); 3}4 5 static void Afnetworkreachabilityreleasecallback (const void *info) {6 if (info) {7 block_release (info); 8 }9}
Setting up network monitoring is divided into the following steps:
1. We'll start with a new context
1 Scnetworkreachabilitycontext context = {0, (__bridge void *) callback, Afnetworkreachabilityretaincallback, Afnetworkreachabilityreleasecallback, NULL};
2. Setting callbacks
1 Scnetworkreachabilitysetcallback (self.networkreachability, Afnetworkreachabilitycallback, &context);
Where this afnetworkreachabilitycallback is defined as a function
typedef void (*scnetworkreachabilitycallback) ( scnetworkreachabilityref target, Scnetworkreachabilityflags flags, void * __nullable info );
In this class
1 static void Afnetworkreachabilitycallback (Scnetworkreachabilityref __unused Target, scnetworkreachabilityflags Flags, void *info) {2 Afpostreachabilitystatuschange (Flags, (__bridge afnetworkreachabilitystatusblock) info); 3 }
3. Join the Runloop Pool
1 Scnetworkreachabilityschedulewithrunloop (self.networkreachability, Cfrunloopgetmain (), kCFRunLoopCommonModes);
where Cfrunloopgetmain() represents the main runloop
OK, it's almost done.
Sends the current network state once on an asynchronous thread.
Stop Network Monitoring
These two methods have nothing to say, one is getter, one is setter
Register the key value dependence, this probably everybody usually uses relatively little. can look
For example, there are two attributes in a class user
There's a card like that.
We write a setter and getter method for info,
1 @interface user:nsobject 2 @property (nonatomic,copy) NSString *name; 3 @property (nonatomic,assign) Nsuinteger age; 4 @end 5 6 7 8 @interface card:nsobject 9 @property (nonatomic,copy) nsstring *info;10 @property (nonatomic,strong) User *user;11 @end12 @implementation card13-(NSString *) info {return [nsstring stringwithformat:@ "%@/%lu", _user.na Me, (unsigned long) _user.age];16}17-(void) SetInfo: (NSString *) Info {Nsarray *array = [Info componentssepar atedbystring:@ "/"];20 _user.name = array[0];21 _user.age = [array[1] integervalue];22 +}24 + (Nsset<ns String *> *) Keypathsforvaluesaffectingvalueforkey: (NSString *) key {Nsset * keypaths = [Super Keypathsforvaluesaf fectingvalueforkey:key];27 Nsarray * morekeypaths = nil;28 if ([Key isequaltostring:@ "info"]) 30 {31 Morekeypaths = [Nsarray arraywithobjects:@ "User.Name", @ "User.age", nil];32}33 if (morekeypaths) 35 {36 Keypaths = [keypathssetbyaddingobjectsfromarray:morekeypaths];37}38 keypaths;40}41 @end
The code is almost the top. We can listen to the Info property of the card, and when the value of name or age in user changes, it triggers the key-value listening method of info. This is the role of key-value dependencies.
Afnetworking 3.0 Source Code interpretation