NSURLConnection for iOS network development and programming

Source: Internet
Author: User

NSURLConnection for iOS network development and programming

Well-known third-party libraries at the iOS network layer, such as ASIHTTPRequest, AFNetworking, and MKNetworkKit. As the ASI is no longer updated, the landlord has basically followed the large army to use AF. AF uses the Cocoa-layer API-NSURLConnection.

I used NSURLConnection in the past. I am not very familiar with many related methods. I took the time to study the NSURLConnection and summarized the usage of NSURLConnection in the evening.


1. attributes and methods of NSURLConnection.

Go to NSURLConnection. h to introduce all methods from top to bottom.

@ Interface NSURLConnection: NSObject

{

@ Private

NSURLConnectionInternal * _ internal;

}


/* Designated initializer */

/*

Create an NSURLConnection. Only the connection is established and no data is downloaded.

Request: request content

Delegate: NSURLConnectionDelegate, the NSURLConnection instance will strongly reference delegate until the callback didFinishLoading, didFailWithErrorNSURLConnection. cancel call. (During the download the connection maintains a strong reference to

delegate. It releases that strong reference when the connection finishes loading, fails, or is canceled)

StartImmediately: whether to download data immediately. YES: download the data immediately and add the connection to the current runloop. NO, only establish connections, do not download data, need to manually

[Connection start] starts to download data.


*/

-(Instancetype) initWithRequest :( NSURLRequest *) request delegate :( id) delegate startImmediately :( BOOL) startImmediately NS_AVAILABLE (10_5, 2_0 );


/*

Actually, [self initWithRequest: request delegate: delegate startImmediately: YES];

Call [connection start] When you do not need to display]


*/

-(Instancetype) initWithRequest :( NSURLRequest *) request delegate :( id) delegate;

/*

Actually, [self initWithRequest: request delegate: delegate startImmediately: YES];

Call [connection start] When you do not need to display]

*/


+ (NSURLConnection *) connectionWithRequest :( NSURLRequest *) request delegate :( id) delegate;


/*

Requests used to establish a connection

*/

@ Property (readonly, copy) NSURLRequest * originalRequestNS_AVAILABLE (10_8, 5_0 );


/*

The authentication protocol for connection establishment requests may change.

As the connection performs the load,

This request may change as a result of protocol

Canonicalization or due to following redirects.

-CurrentRequest can be used to retrieve this value.

*/


@ Property (readonly, copy) NSURLRequest * currentRequestNS_AVAILABLE (10_8, 5_0 );


/*

Start to download data. Use-(instancetype) initWithRequest :( NSURLRequest *) request delegate :( id) delegate startImmediately :( BOOL) startImmediately to call the connection start]

*/

-(Void) startNS_AVAILABLE (10_5, 2_0 );

/*

Disconnect the network and cancel the request. The cancel method cannot guarantee that the proxy callback will not be called immediately (it should be the requested data and can only be passed to the proxy). cancel will release delegate

*/

-(Void) cancel;

/*

Add the connection instance callback to a runloop. The NSURLConnectionDelegate callback will respond in this runloop.

Note that this method cannot be set at the same time as setDelegateQueue. You can only select one.

*/

-(Void) scheduleInRunLoop :( nsunloop *) aRunLoop forMode :( NSString *) modeNS_AVAILABLE (10_5, 2_0 );

/*

Cancel the callback in this runloop.

*/

-(Void) unscheduleFromRunLoop :( nsunloop *) aRunLoop forMode :( NSString *) modeNS_AVAILABLE (10_5, 2_0 );


/*

If a queue is set, the callback will be performed on this queue. A callback is similar to adding an NSBlockOperation to the queue.

Note that this method cannot be set at the same time as scheduleInRunLoop. You can only select one.


*/

-(Void) setDelegateQueue :( NSOperationQueue *) queueNS_AVAILABLE (10_7, 5_0 );


@ Interface NSURLConnection (NSURLConnectionSynchronousLoading)


/*

Class to create a synchronization request. This method is based on Asynchronization and then blocks the implementation of the current thread.

Response: response Header Information, passing a two-dimensional pointer

Error: status of the request result

*/

+ (NSData *) sendSynchronousRequest :( NSURLRequest *) request returningResponse :( NSURLResponse **) response error :( NSError **) error;


@ End


@ Interface NSURLConnection (NSURLConnectionQueuedLoading)


/*

Initiate an asynchronous request

Queue: completionHandler will run in this queue

CompletionHandler: Request callback block

*/

+ (Void) sendAsynchronousRequest :( NSURLRequest *) request

Queue :( NSOperationQueue *) queue

CompletionHandler :( void (^) (NSURLResponse * response, NSData * data, NSError * connectionError) handlerNS_AVAILABLE (10_7, 5_0 );

@ End


Ii. NSURLConnection usage


The above method is almost introduced. Try writing a few demos.

First, define some basic configurations.

Static char * const URLSTRING = "http://f.hiphotos.baidu.com/image/h%3D200/sign=a1217b1330fa828bce239ae3cd1f41cd/0e2442a7d933c895cc5c676dd21373f082020081.jpg ";


-(NSURLRequest *) request {

NSString * urlString = [nsstringstringwithuf8string: URLSTRING];

NSURL * url = [NSURLURLWithString: urlString];

NSURLRequest * request = [NSURLRequestrequestWithURL: url

CachePolicy: NSURLRequestReloadIgnoringLocalAndRemoteCacheData

TimeoutInterval: 30.f];

Return request;

}


In addition, an NSURLConnectionDelegate class is abstracted to implement NSURLConnectionDelegate. In this way, you do not need to write a lot of protocols when using NSURLConnection elsewhere.

# Import


Typedefvoid (^ NSURLConnectionCompeletionBlock) (id );


@ Interface NSURLConnectionDelegate: NSObject

@ Property (nonatomic, strong, readonly) NSOutputStream * OS;

@ Property (nonatomic, assign, readonly) BOOL isFinish;

@ Property (nonatomic, strong, readonly) NSMutableData * buffer;

@ Property (nonatomic, assign, readonly) NSUInteger contentLength;

@ Property (nonatomic, strong) NSURLConnectionCompeletionBlock completionBlock;

@ End


# Import "NSURLConnectionDelegate. h"


@ Implementation NSURLConnectionDelegate


-(Void) dealloc

{

NSLog (@ "__% s _" ,__ FUNCTION __);

}



-(Void) connectionDidFinishLoading :( NSURLConnection *) connection {


If (self. completionBlock ){

Self. completionBlock ([self. ospropertyForKey: NSStreamDataWrittenToMemoryStreamKey]);

}

[Self. osclose];


_ IsFinish = YES;

}

-(Void) connection :( NSURLConnection *) connection didReceiveResponse :( NSURLResponse *) responsez {

If ([responsez isKindOfClass: [NSHTTPURLResponseclass]) {

NSHTTPURLResponse * hr = (NSHTTPURLResponse *) responsez;

If (hr. statusCode = 200 ){

_ ContentLength = hr. expectedContentLength;

// _ OS = [NSOutputStream outputStreamToFileAtPath: [NSHomeDirectory () stringByAppendingPathComponent: @ "Documents/image.jpg"] append: NO];

_ OS = [NSOutputStreamoutputStreamToMemory];


[_ Osopen];

}

}

}


-(Void) connection :( NSURLConnection *) connection didFailWithError :( NSError *) error {

If (self. completionBlock ){

NSError * error = [NSErrorerrorWithDomain: error. domain

Code: error. code

UserInfo: error. userInfo];

Self. completionBlock (error );

}

_ IsFinish = YES;

[Self. osclose];

}


-(Void) connection :( NSURLConnection *) connection didReceiveData :( NSData *) data {

If (! Self. buffer ){

_ Buffer = [NSMutableDatadataWithCapacity: self. contentLength];

}

[Self. bufferappendData: data];

//

NSUInteger totalLength = data. length;

NSUInteger totalWirte = 0;

Const uint8_t * datas = data. bytes;

While (totalWirte <totalLength ){

/*

The number of bytes actually written, or-1 if an error occurs. more information about the error can be obtained with streamError. if the specified er is a fixed-length stream and has reached its capacity, 0 is returned.

*/

NSInteger writeLength = [self. oswrite: & datas [totalWirte] maxLength :( totalLength-totalWirte)];

If (writeLength =-1 ){

[Connectioncancel];

Break;

}

TotalWirte + = writeLength;

NSLog (@ "totalLenght = % lu, totalWirte = % lu", totalLength, totalWirte );

}

}




Write NSOperation together

# Import


@ Interface NSURLConnectionOperation: NSOperation


@ Property (nonatomic, strong) NSURLRequest * request;

@ Property (nonatomic, strong) NSData * buffer;



-(Instancetype) initWithRequest :( NSURLRequest *) request;

-(Void) startAsync;

@ End


# Import "NSURLConnectionOperation. h"

# Import "NSURLConnectionDelegate. h"


@ Interface NSURLConnectionOperation ()

@ Property (nonatomic, assign, getter = isExecuting) BOOL executing;

@ Property (nonatomic, assign, getter = isFinished) BOOL finished;

@ Property (nonatomic, assign, getter = isConcurrent) BOOL concurrent;

@ Property (nonatomic, strong) NSThread * thread;

@ Property (nonatomic, strong) NSURLConnection * connection;

@ End


@ Implementation NSURLConnectionOperation

@ Synthesize executing = _ executing, finished = _ finished, concurrent = _ concurrent;


-(Void) dealloc

{

NSLog (@ "% s" ,__ FUNCTION __);

}


-(Instancetype) initWithRequest :( NSURLRequest *) request {

Self = [superinit];

If (self ){

Self. request = request;

}

Return self;

}

-(Void) start {

If (! Self. thread ){

_ Thread = [NSThreadcurrentThread];

}

Self. finished = NO;

Self.exe cuting = YES;

_ WeakNSURLConnectionOperation * wkSelf = self;

NSURLConnectionDelegate * delegate = [NSURLConnectionDelegatenew];

Delegate. completionBlock = ^ (id data ){

If (! WkSelf. buffer ){

WkSelf. buffer = data;

}

// Broadcast the notification and execute completionBlock

WkSelf. finished = YES;

WkSelf.exe cuting = NO;

};

_ Connection = [[NSURLConnectionalloc] initWithRequest: self. request

Delegate: delegate // keep delegate strongly referenced

StartImmediately: NO];

// Manually set runloop to default before start

[_ ConnectionscheduleInRunLoop: [nsunloopcurrentrunloop] forMode: NSDefaultRunLoopMode];

[_ Connection start];

While (! Self. isFinished ){

[[Nsunloopcurrentrunloop] runMode: NSDefaultRunLoopModebeforeDate: [NSDatedistantFuture];

}

NSLog (@ "start end !! ");

}

-(Void) startAsync {

_ Thread = [[NSThreadalloc] initWithTarget: selfselector: @ selector (start) object: nil];

[Self. threadstart];

}



-(Void) setFinished :( BOOL) finished {

[SelfwillChangeValueForKey: @ "isFinished"];

_ Finished = finished;

[SelfdidChangeValueForKey: @ "isFinished"];


}

-(Void) setExecuting :( BOOL) executing {

[SelfwillChangeValueForKey: @ "isExecuting"];

_ Executing = executing;

[SelfdidChangeValueForKey: @ "isExecuting"];

}

-(BOOL) isConcurrent {

Return YES;

}




@ End







Synchronous request:

-(IBAction) sync :( id) sender {

[SelfprintGO];

//

NSURLResponse * response = nil;

NSError * error = nil;

NSData * data = [NSURLConnectionsendSynchronousRequest: [selfrequest]

ReturningResponse: & response

Error: & error];

NSLog (@ "get sync data! ");

If ([response isKindOfClass: [NSHTTPURLResponseclass]) {

NSHTTPURLResponse * hr = (NSHTTPURLResponse *) response;

If (hr. statusCode = 200 ){

NSLog (@ "sync repsonse head: \ n % @", hr. allHeaderFields );

Self. imageView. image = [UIImageimageWithData: data];

}

}


[SelfprintEnd];

}

-(IBAction) sync :( id) sender {

[SelfprintGO];

NSURLConnectionOperation * operation = [[NSURLConnectionOperationalloc] initWithRequest: [selfrequest];

_ Weak NSURLConnectionOperation * wkOp = operation;

Operation. completionBlock = ^ {

_ StrongNSURLConnectionOperation * sOp = wkOp; // prevents wkOp from being released and strongly referenced

NSLog (@ "set? ");

Dispatch_async (dispatch_get_main_queue (), ^ {

Self. imageView. image = [uiimagewithdata: sOp. buffer];

});

};

[Operationstart];

[SelfprintEnd];

}



Asynchronous request:

-(IBAction) async :( id) sender {

[SelfprintGO];

// **************************** NSURLConnection async

// This method can only initiate a simple request and wait for the result, which is inconvenient for statistics.

[NSURLConnectionsendAsynchronousRequest: [selfrequest]

Queue: self. queue // completionHandler run on this queue

CompletionHandler: ^ (NSURLResponse * response, NSData * data, NSError * connectionError ){

If ([response isKindOfClass: [NSHTTPURLResponseclass]) {

NSHTTPURLResponse * hr = (NSHTTPURLResponse *) response;

If (hr. statusCode = 200 ){

[SelfprintCurrentThread];

Self. imageView. image = [UIImageimageWithData: data];

}

}

}];

[SelfprintEnd];


}


-(IBAction) async :( id) sender {

[SelfprintGO];

NSURLConnectionDelegate * connectionDelegate = [NSURLConnectionDelegatenew];

ConnectionDelegate. completionBlock = ^ (id data ){

[SelfprintCurrentThread];

If ([data isKindOfClass: [NSDataclass]) {

[[NSOperationQueuemainQueue] addOperationWithBlock: ^ {

Self. imageView. image = [UIImageimageWithData: data];


}];

}

};

NSURLConnection * connection = [[NSURLConnectionalloc] initWithRequest: [selfrequest] delegate: connectionDelegate];

// The delegate callback is completed in the thread opened by the current operationqueue

// [Connection scheduleInRunLoop: [nsunloop currentRunLoop] forMode: NSDefaultRunLoopMode];

[ConnectionsetDelegateQueue: self. queue];

[Connectionstart];

[SelfprintEnd];


}



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.