Analysis of Mknetworkkit Development framework of OBJECTIVE-C _ios

Source: Internet
Author: User
Tags gcd json

What is Mknetworkkit?

Mknetworkkit is a o-c-written network framework that supports blocks, arcs, and is simple to use.

Mknetworkkit set ASIHTTPRequest and afnetworking two frameworks in one. In addition to integrating the excellent features of both, a new stack of features is added. In particular, it makes it easier for you to write code than other frameworks. It keeps you away from the disgusting web code.

Characteristics

Ultra Lightweight Framework

The entire framework has only 2 classes and some category methods. Therefore, its use is extremely simple.

There is only one global queue in the entire program.

Apps that are highly reliant on Internet connections should prioritize the number of concurrent network threads. Unfortunately, no network framework has been good enough in this area. Therefore, once you do not control the number of concurrent network threads in the program, it is very easy to cause errors.

Let's say you want to upload a bunch of pictures to the server. Most mobile networks (3G) will not allow you to have more than 2 HTTP concurrent connections to the same IP address. In other words, you can't get more than 2 HTTP concurrent connections from a 3G network on a device. For the Edge is even worse, most of the case can not exceed 1. Compared to home broadband network (WIFI), this limit is much wider (6). However, you cannot always use WiFi, and you must also consider the connectivity of a limited network (narrowband). More often than not, idevice devices can connect to 3G networks, so you can upload only 2 images at the same time. But the real problem is not the slow upload speed, but the other. When you open a view to try to load a thumbnail (different view), the upload thread is run to the background. If you don't control the number of threads in the upload queue, your thumbnail will load overtime. This is not normal. The correct way is to optimize the thumbnail load thread, or let the thread wait until the upload completes before loading the thumbnail. This requires you to have only one queue in the entire program.

Mknetworkkit uses a single example in each of its instances to ensure this. It is not that Mknetworkkit is a single case, but that its shared queue is a single example.


Common frame such as: Afnetworking,asihttprequest,sdwebimage,mknetworkit.
Now Mknetworkki absorbs the advantages of asihttprequest and afnetworking, and adds its own unique function.

Download:

GitHub Address: Https://github.com/MugunthKumar/MKNetworkKit.git

Official Use note: http://blog.mugunthkumar.com/products/ios-framework-introducing-mknetworkkit/

GitHub Download the project, if you want to run its demo, be sure to open mknetworkkit.xcworkspace the file, if opened separately, the compile will prompt the lack of LIBMKNETWORKKIT-IOS.A files!!!

Installation:

After cloning, drag the Mknetworkkit folder into the project, and then introduce 3 frameworks:

Note: Because Mknetworkkit supports arc, we'll open the arc in the project, or we'll make an error.

Turn on the ARC automatic Memory control mechanism: (All Dealloc, release, autorelease in the project will be commented out after opening the arc)

How to use:

Import where needed: #import "MKNetworkKit.h"
Display network status instructions correctly

Many 3rd party frameworks display network status through a callback to "increase/decrease the number of network Connections", and Mknetworkkit can automatically display network status because of the use of a single example of shared queues. A thread in a Shared queue can observe the Operationcount property at any time by KVO. So for developers, there is generally no need to worry about the display of network status.

Copy Code code as follows:

if (object = = _sharednetworkqueue && [keypath isequaltostring:@ "Operationcount"]) {

[UIApplication sharedapplication].networkactivityindicatorvisible = ([_sharednetworkqueue.operations count] < 0) ;

}


automatically change queue size

As mentioned earlier, most mobile networks do not allow more than 2 concurrent connections, so your queue size should be set to 2 under 3G network. Mknetworkkit will handle this for you automatically. When the network is out of 3G/EDGE/GPRS, it adjusts the concurrency to 2. Automatically adjusts to 6 when the network is on a Wifi network. When you load thumbnails from a remote server over a 3G network, this adjustment can bring great benefits.

Automatic Caching

Mknetworkkit can automatically cache all of your get requests. When you initiate the same request again, Mknetworkkit can then invoke the response cache (if available) and pass it to handler for processing. Of course, it also makes a request to the server. Once the server data is obtained, handler is again required to process the newly acquired data. In other words, you do not have to manually cache. You only need to use:

Copy Code code as follows:

[[Mknetworkengine Sharedengine] usecache];

Of course, you can override this method (subclass) to customize your cache path and cache memory overhead.

Freeze Network operations

Mknetworkkit can "freeze" network operations. When a network operation is "Frozen", once the network connection is disconnected, they are automatically serialized and automatically submitted once when the device is wired again. "Drafts" like a Twitter client.

When you submit a tweet, the mknetworkkit automatically freezes and stores the requests if the network is marked as "Frozen." So the tweet will be delayed in the future. The whole process does not require you to write a single line of code. This feature you can use for other operations, such as collecting a tweet or sharing a post from a Goolge reader client, adding a link to the Instapaper, and so on.

A similar request performs only one action:

When you load thumbnails (for the Twitter stream), you end up creating a new request for each actual picture. In fact, many of the requests you make are the same URL. Mknetworkkit is only executed once for each GET request in the queue. It is not yet able to cache POST requests.

Picture caching

The Mknetworkkit has a built-in thumbnail cache. As long as you cover several methods, you can set the maximum number of images that can be cached in memory and the cache to be saved to the directory. Of course, you can also not cover these methods.

Performance

That's speed. The Mknetworkkit cache is built-in, as in Nscache, when memory warnings are found, data cached in memory is written to the cached directory.

Full support for ARC

Generally you will only use the new network framework in the new project. Mknetworkkit does not mean abandoning the existing framework (you can also give up, which is a tedious job). For new projects, you always want to use ARC. When you see this article, it is likely that Mknetworkkit will be the only network framework that fully supports ARC. ARC is usually faster than non-arc code.

Usage

OK, I will not "puff". Let's immediately understand if you use this framework.

Add Mknetworkkit

Drag the Mknetworkkit directory to the project

Add the following frames: Cfnetwork.framework, Systemconfiguration.framework, Security.framework and Imageio.framework.

To include a MKNetworkKit.h header file in a PCH file

For IOS, delete nsalert+mknetworkkitadditions.h

For Mac, delete uialertview+mknetworkkitadditions.h

A total of only 5 core files, really a powerful network development package

Mknetworkkit's Class

Mknetworkoperation

Mknetworkengine

Some tool classes (Apple's reachability) and categories

I like simplicity. Apple has written the most basic and core network code. The 3rd party framework needs to provide an elegant network queue plus a cache. I don't think the 3rd party framework should be more than 10 classes (whether it's a network or a uikit or something). It's too bloated to exceed this number. THREE20 is an example. Now Sharekit is like this again. Although they are excellent, they are still huge and bloated. ASIHTTPRequest or afnetworking is lighter than restkit, and Jsonkit is lighter than Touchjson (or any Touchcode library). This is only my own opinion, but when a third party library code exceeds the program source code 1/3, I will not use it.

The problem with a bloated framework is that it's hard to understand its internal working mechanism and it's hard to tailor it to your needs (when you need it). Some of the frameworks I've written (such as Mkstorekit, for apps) are always easy to use, and I think mknetworkkit should be. For Mknetworkkit, all you need to know is the methods exposed to the two classes of mknetworkoperation and Mknetworkengine. Mknetworkoperation is like ASIHTTPRequest class. It is a nsoperation subclass that encapsulates your request and response classes. For each network operation, you need to create a mknetworkoperation.

Mknetworkengine is a pseudo single instance class that manages the network queues in a program. It is a pseudo single example, that is, for simple requests, you can use the Mknetworkengine method directly. To make a deep customization, you should subclass it. Each mknetworkengine subclass has its own reachability object that notifies it of reachability notifications from the server. For different REST servers, you can consider creating separate mknetworkengine subclasses.

It is a pseudo single case, and each request for its subclass has a unique queue. You can retain this mknetworkengine in an application delegate, just like the Managedobjectcontext class of CoreData. When using Mknetworkkit, create a mknetworkengine subclass to logically group your network requests. For example, put all of Yahoo's methods in one class, and all Facebook-related methods are put into another class. Take a look at 3 examples of actual use.

Example 1:

Create a "yahooengine" to capture the currency exchange rate from Yahoo financial server.

Step 1: Create the Yahooengine class to inherit from Mknetworkengine. Mknetworkengine uses the hostname and the specified header (if any) to initialize it. Header information can be nil. If you are on your REST server, consider adding a version of the client app or other information (such as the client's identity).

Copy Code code as follows:

Nsmutabledictionary *headerfields = [Nsmutabledictionary dictionary]; [Headerfields setvalue:@ "IOS" forkey:@ "X-client-identifier"];

Self.engine = [[Yahooengine alloc] initwithhostname:@ "download.finance.yahoo.com" Customheaderfield S:headerfields];


Note that Yahoo does not recognize that you send x-client-identifier to it in the header, this example simply demonstrates this feature and

With the ARC code, you need to have a (strong reference) engine object as a developer.

Once you create a mknetworkengine subclass, Reachability is automatically implemented. Your request will be frozen automatically when your server is blocked due to certain conditions and the host name is inaccessible. Refer to the "Freezing operations" section later on for "freezing."

Step 2: Design the engine class (focus on separation)

Now, start writing a method in Yahoo Engine to capture the exchange rate. These methods will be invoked in the Viewcontroller. A good design experience is to make sure that the url/httpheaders in the engine class is not exposed to the caller. Your view should not know the URL or the relevant parameters. That is, you just have to pass the currency type and currency unit to the engine method. The return value of the method may be double, which is the exchange rate, and when the exchange rate is obtained. Because it is an asynchronous operation, you should return these values in the block. For example:

Copy Code code as follows:

-(mknetworkoperation*) Currencyratefor: (nsstring*) sourcecurrency

Incurrency: (nsstring*) targetcurrency

Oncompletion: (currencyresponseblock) Completion

OnError: (errorblock) error;

In the parent class Mknetworkengine, 3 block types are defined:

typedef void (^progressblock) (double progress);

typedef void (^responseblock) (mknetworkoperation* operation);

typedef void (^errorblock) (nserror* error);


In Yahooengine, we used a new block type: Currencyresponseblock to return the exchange rate. The definition is as follows:

typedef void (^currencyresponseblock) (double rate);

In other formal apps, you should define your own blocks similar to Currencyresponseblock to return data to Viewcontroller.

Step 3: Process the data
Process data, including data type conversions from data captured from the server, such as json/xml/plists. This should be done in Engine. Note, do not complete in the controller. Your Engine should return the data to an array of appropriate model objects or model objects. Convert Json/xml to model in engine-note that with proper attention to separation, view controller should not know any key to access the JSON node. This thought dominates the design of the engine. Many network frameworks do not force you to obey the separation of concerns, and we do so because we consider it for you.

Step 4: Implementing the method
Now, let's discuss the method implementation details. To obtain exchange rate information from Yahoo, the simplest is to initiate a GET request. The following macro formats the URL string with a pair of specified currencies:

We'll now discuss the implementationdetails of this method, calculates your currency exchange.

Getting currency information from Yahoo,is as simple as making a GET request.
I wrote a macro to the format this URL for a given currency pair.

#define YAHOO_URL (__c1__, __c2__) [NSString stringwithformat:@ "D/quotes.csv?e=.csv&f=sl1d1t1&s=%@%@=x", __ c1__, __c2__]

Write the engine class method in the following order:

Prepare URLs based on parameters

Create a Mknetworkoperation object

Set Method parameters

Sets the completion block and error block for operation (handles response in a completation block and converts to a model)

Optionally, add a progress block (or do this in the view controller)

If operation is a download, set up the download stream (usually a file). This step is optional.

When operation completes, the result is processed and the method block is called and the data is returned to the caller.

The sample code is as follows:

Copy Code code as follows:

Mknetworkoperation *op = [Selfoperationwithpath:yahoo_url (sourcecurrency, targetcurrency)

Params:nil

httpmethod:@ "Get"];

[Op oncompletion:^ (mknetworkoperation*completedoperation)

{

Dlog (@ "%@", [completedoperation responsestring]);

Do your processing

Completionblock (5.0f);

}onerror:^ (nserror* error) {

Errorblock (Error);

}];

[Self enqueueoperation:op];

return op;


The above code formats the URL and creates a mknetworkoperation. After the completion and error blocks are set, operation is added to the queue (through the Enqueueoperation method of the parent class) and a reference to operation is returned. Therefore, if you call this method in Viewdidappear, the operation is canceled in the Viewwilldisappear method. Canceling operation frees operation to perform operation for other view in the queue (remember that only 2 operation in the mobile network can be performed simultaneously, and when operation is no longer needed, it can boost the app's Performance and Speed).

You can also add a progress block to refresh the UI in Viewcontroller. For example:

Copy Code code as follows:

[Self.uploadoperation onuploadprogresschanged:^ (Double progress) {

Dlog (@ "%.2f", progress*100.0);

Self.uploadProgessBar.progress = progress; }];


Mknetworkengine also has a useful way to create operation only with URLs. So the 1th line of code can also be written as:

Mknetworkoperation *op = [Self Operationwithpath:yahoo_url (sourcecurrency, targetcurrency)];

Note that the requested URL is automatically added to the host name (specified when engine is instantiated).

There are a lot of practical methods like this mknetworkengine, you can view header files.

Example 2:

Upload pictures to the server (for example, Twitpic).
Now let's look at an example of uploading a picture to a server. To upload a picture, it is obvious that operation can encode multi-part form data. Mknetworkkit uses a similar asihttprequest approach.
You can easily submit a file as a multi-part form data in the request through the Mknetworkoperation Addfile:forkey: method.

Mknetworkoperation also has a way to submit pictures in a nsdata way. Adddata:forkey: Method that can upload a picture to the server in a NSData way. (for example, pictures captured directly from the camera).

Example 3:

Download files to local directory (cache)
Using Mknetworkkit to download files from the server and save them to the IPhone's local directory is simple.

You only need to set the Mknetworkoperation outputstream.

[Operation Setdownloadstream:[nsoutputstream outputstreamtofileatpath:@ "/users/mugunth/desktop/ Downloadedfile.pdf "Append:yes]";

You can set up multiple outputstream to a operation and save the same file in several places (for example, one is your cache directory and the other is used for your working directory).

Example 4:

Caching thumbnail images of pictures

For downloading pictures, you may need to provide an absolute URL address instead of a path.
Mknetworkengine's OperationWithURLString:params:httpMethod: method creates a network thread based on an absolute URL address.

Mknetworkengine is quite clever. It merges multiple get requests for the same URL into one and notifies all blocks when the operation is complete. This significantly improves the crawl image URL to render the thumbnail faster.

Subclass Mknetworkengine then overwrites the picture's cache directory and the size of the cache. If you don't want to customize both, you can simply call the Mknetworkengine method to download the picture. This is what I highly recommend.

Cache operation

Mknetworkkit all requests are cached by default. All you need is just to open it in your own engine. When a GET request is executed, if the last response has been cached, the corresponding completion block will be invoked with the cached response (instantaneous). To know if response is cached, you can call the Iscachedresponse method as follows:

Copy Code code as follows:

[Op oncompletion:^ (mknetworkoperation *completedoperation) {

if ([Completedoperation Iscachedresponse]) {

Dlog (@ "Data from cache");

}else {

Dlog (@ "Data from server");

}

Dlog (@ "%@", [completedoperation responsestring]);

}

onerror:^ (nserror* error) {

Errorblock (Error);

}];


Freeze operation

One of the most interesting features of Mknetworkkit is its built-in frozen operation feature. You just have to set the operation Freeesable attribute. There's almost nothing to do!

[Op Setfreezable:yes];

Freezing is when the operation is automatically serialized when the network is disconnected and automatically executed after the network is restored. For example, when you are offline, you can also do a collection of tweets, and then when you are online again, operation automatically resumes execution.

Frozen operation are also persisted to disk as the application enters the background. It then resumes execution automatically after the application returns to the foreground.

A useful method in Mknetworkoperation

As shown below, Mknetworkoperation exposes a number of useful methods from which you can obtain response data in a variety of formats:

Copy Code code as follows:

ResponseData

Responsestring

Responsejson (only on IOS 5)

Responseimage

Responsexml

Error


These methods are used to get the response data when the operation is finished executing. If the format is not correct, the method returns nil. For example, the response data is clearly an HTML format, and you will only get nil with the Responseimage method. Only responsedata can guarantee that whatever format is returned correctly, other methods you must make sure to match the corresponding Repsone type.

Useful macros

Dlog and Alog macros were shamelessly stolen from StackOverflow, and I couldn't find the source author. If you wrote it, please let me know.

A little note on the GCD

Because the network thread may be able to be stopped or prioritized, I decisively gave up the GCD--GCD efficiency is higher than the nsoperation, but it does not do that. I recommend that you do not use GCD queues on your network threads either.

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.