IOS network programming (6) NSURLSession

Source: Internet
Author: User
Tags tmp folder

When I browsed the Demo last night, I saw that someone else used NSURLSession to request network data. At that time, I was wondering what was going on here. Why didn't I use it? It aroused my curiosity, I went to Baidu-Google-official documents to view them one by one. I had some knowledge that NSURLSession was a new network interface in iOS7, And it is tied to the familiar NSURLConnection. I searched for the materials and wrote a Demo. You can check out the shortcomings and leave a message to help me point out the shortcomings.

//// HMTRootViewController. m ///// Created by HMT on 14-6-7. // Copyright (c) 2014 Hu mingtao. all rights reserved. // # import "HMTRootViewController. h "# import" HMTAppDelegate. h "@ interface HMTRootViewController () @ property (nonatomic, strong) UIImageView * imageView; @ property (nonatomic, strong) UIProgressView * progressIndicator; @ property (nonatomic, strong) NSURLSession * urlSession; // normal session // @ property (nonatomic, Strong) NSURLSession * backgroundSession; // background session @ property (nonatomic, strong) NSURLSessionDownloadTask * sessionDownloadTask; // download Task @ property (nonatomic, strong) into * resumableTask; // resume download Task @ property (nonatomic, strong) NSURLSessionDownloadTask * backgroundTask; // download Task @ property (nonatomic, strong) NSData * partialData in the background; // download local data @ end @ implementation HMTRootViewController-(id) I NitWithNibName :( NSString *) nibNameOrNil bundle :( NSBundle *) handle {self = [super initWithNibName: nibNameOrNil bundle: role]; if (self) {// Custom initialization} return self ;} -(void) viewDidLoad {[super viewDidLoad]; self. imageView = [[UIImageView alloc] initWithFrame: CGRectMake (0, 64,320,300)]; [self. view addSubview: _ imageView]; self. progressIndicator = [[UIProgressView alloc] InitWithProgressViewStyle: UIProgressViewStyleDefault]; _ progressIndicator. frame = CGRectMake (50,500,220, 50); [self. view addSubview: _ progressIndicator]; UIButton * cancleButton = [UIButton buttonWithType: UIButtonTypeSystem]; cancleButton. frame = CGRectMake (120,400, 40, 40); [cancleButton setTitle: @ "cancel" forState: UIControlStateNormal]; [cancleButton addTarget: self action: @ selector (didClickCancle ButtonAction :) forControlEvents: UIControlEventTouchUpInside]; [self. view addSubview: cancleButton]; UIButton * downloadButton = [UIButton buttonWithType: UIButtonTypeSystem]; downloadButton. frame = CGRectMake (20,400, 40, 40); [downloadButton setTitle: @ "Download" forState: UIControlStateNormal]; [downloadButton addTarget: self action: @ selector (success :) forControlEvents: UIControlEventTou ChUpInside]; [self. view addSubview: downloadButton]; UIButton * uploadButton = [UIButton buttonWithType: UIButtonTypeSystem]; uploadButton. frame = CGRectMake (70,400, 40, 40); [uploadButton setTitle: @ "Upload" forState: UIControlStateNormal]; [uploadButton addTarget: self action: @ selector (didClickUploadButtonAction :) forControlEvents: UIControlEventTouchUpInside]; [self. view addSubview: uploadButton]; UIButto N * resumableButton = [UIButton buttonWithType: UIButtonTypeSystem]; resumableButton. frame = CGRectMake (180,400, 40, 40); [resumableButton setTitle: @ "Restore" forState: UIControlStateNormal]; [resumableButton addTarget: self action: @ selector (didClickResuableButtonAction :) forControlEvents: UIControlEventTouchUpInside]; [self. view addSubview: resumableButton]; UIButton * backgroundLoadButton = [UIButton butto NWithType: UIButtonTypeSystem]; backgroundLoadButton. frame = CGRectMake (220,400, 80, 40); [backgroundLoadButton setTitle: @ "" forState: UIControlStateNormal]; [backgroundLoadButton addTarget: self action: @ selector (handler :) forControlEvents: UIControlEventTouchUpInside]; [self. view addSubview: backgroundLoadButton]; # pragma mark-if we want to use NSURLSession for data transmission, we need to:/*** create An NSU RLSessionConfiguration is used to set the working mode when NSSession is created (3) * (1) default mode: the working mode is similar to the original NSURLConnection. Cache, Cookie, and authentication can be used. * (2) instant mode (ephemeral): Cache, Cookie, and authentication are not used. * (3) background: complete upload and download in the background, when creating the Configuration object, you need to give an NSString ID to track which Session is used to complete the work */NSURLSessionConfiguration * sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];/*** @ network settings: refer to the setting item * In NSURLConnection for the two creation methods (which are not quite different at present) * (1) create a Session based on the Configuration just created, by default, the system creates a new OperationQueue to process Session messages. * (2) You can set the callback delegate (note that the callback delegate will be strongly referenced), and you can set the OperationQueue callback of the delegate, for example If we set * to [NSOperationQueue mainQueue], it is very convenient to callback in the main thread * // NSURLSession * session = [NSURLSession sessionWithConfiguration: sessionConfig]; self. urlSession = [NSURLSession sessionWithConfiguration: sessionConfig delegate: self delegateQueue: [NSOperationQueue mainQueue]; NSURL * url = [NSURL URLWithString: @ "http://www.bizhiwa.com/uploads/allimg/2012-01/22021207-1-311536.jpg"]; NSURLRequest * request [NSURLRequest requestWithURL: url];/*** NSURLSessionUploadTask: The Task used for upload. The returned results will not be downloaded after being uploaded; * NSURLSessionDownloadTask: The Task used for download; * NSURLSessionDataTask: you can upload the content before downloading it. */Self. sessionDownloadTask = [self. urlSession downloadTaskWithRequest: request]; // Like NSURLConnection, a proxy method also has a block method. // [session dataTaskWithRequest: request completionHandler: ^ (NSData * data, NSURLResponse * response, NSError * error) {//}] ;}# pragma mark click Download-(void) didClickDownloadButtonAction :( UIButton *) button {// because the task is suspended by default, task to be restored (Execution task) [_ sessionDownloadTask resume];} # pragma mark Click Upload-(void) DidClickUploadButtonAction :( UIButton *) button {// determines whether the imageView has content if (_ imageView. image = nil) {NSLog (@ "image view is empty"); return;} // 0. add the indicator UIActivityIndicatorView * indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray] on the interface before uploading. // set the location ??? CGSize size = _ imageView. bounds. size; indicator. center = CGPointMake (size. width/2.0, size. height/2.0); [self. imageView addSubview: indicator]; [indicator startAnimating]; // 1. url nsurl * url = [NSURL URLWithString: @ "http://www.bizhiwa.com/uploads/allimg/2012-01/22021207-1-311536.jpg"]; // 2. request-> PUT. The default request operation is GET NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL: url CachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval: 5.0f]; request. HTTPMethod = @ "PUT"; // *** sets the network request authentication! * ** // 1> authorization string NSString * authStr = @ "admin: 123456"; // 2> BASE64 encoding to prevent data from being transmitted in plaintext over the network. // iOS, only BASE64 encoding is supported for NSData-type data. NSData * authData = [authStr dataUsingEncoding: NSUTF8StringEncoding]; NSString * encodeStr = [authData base64encodedstringwitexceptions: encoding]; NSString * authValue = [NSString stringWithFormat: @ "Basic % @", encodeStr]; [request setValue: authValue ForHTTPHeaderField: @ "Authorization"]; // 3. session NSURLSessionConfiguration * sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession * session = [NSURLSession sessionWithConfiguration: sessionConfig delegate: self resume: [distinct mainQueue]; // 4. uploadTask NSData * imageData = UIImageJPEGRepresentation (_ imageView. image, 0.75); // Application block Request Method NSURLSe SsionUploadTask * uploadTask = [session uploadTaskWithRequest: request fromData: imageData completionHandler: ^ (NSData * data, NSURLResponse * response, NSError * error) {// After the upload is complete, if the data parameter is converted to string, NSString * str = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; NSLog (@ "OK-> % @", str ); [NSThread sleepForTimeInterval: 5.0f]; dispatch_async (dispatch_get_main_queue (), ^ {[indicat Or stopAnimating]; [indicator removeFromSuperview];}) ;}]; // because the task is suspended by default, You need to resume the task (execute the task) [uploadTask resume];} # pragma mark click Cancel // once NSURLConnection is sent, it cannot be canceled. However, we can easily cancel an NSURLSessionTask-(void) didClickCancleButtonAction :( UIButton *) button {/***. After cancellation, this URLSession: task: didCompleteWithError: proxy method to notify you to promptly update the UI. When a task is canceled, * it is very likely that the agent method URLSession: downloadTask: didWriteData: BytesWritten: totalBytesExpectedToWrite: * will be called back again. Of course, the didComplete method must be the last callback. * // If (_ sessionDownloadTask) {// cancel the download request // [_ sessionDownloadTask cancel]; // _ sessionDownloadTask = nil; //} if (! Self. sessionDownloadTask) {// stop the download task and save the data to be restored to a variable to facilitate subsequent download and use [self. sessionDownloadTask cancelByProducingResumeData: ^ (NSData * resumeData) {self. partialData = resumeData; self. sessionDownloadTask = nil;}] ;}# pragma mark resume download (resumable download)-(void) didClickResuableButtonAction :( UIButton *) button {if (self. partialData) {self. sessionDownloadTask = [self. urlSession downloadTaskWithResumeData: self. partialDa Ta]; self. partialData = nil;} else {NSURLRequest * request = [NSURLRequest requestWithURL: [NSURL URLWithString: @ "http://pic4.duowan.com/wow/1002/130782267821/130782458426.jpg"]; self. resumableTask = [self. urlSession downloadTaskWithRequest: request];} [self. sessionDownloadTask resume] ;}# pragma mark background download mode-(void) didClickBackgroundButtonAction :( UIButton *) button {NSURLRequest * request = [NSURLReque St requestWithURL: [NSURL URLWithString: @ "http://dldir1.qq.com/qqfile/QQforMac/QQ_V3.1.2.dmg"]; self. backgroundTask = [[self backgroundSession] downloadTaskWithRequest: request]; [self. backgroundTask resume] ;}# pragma mark-completion // download completed-(void) URLSession :( NSURLSession *) session downloadTask :( NSURLSessionDownloadTask *) downloadTask didFinishDownloadingToURL :( NSURL *) locati On {/*********-> method typedef void (^ MyBlock) (); @ property (copy, nonatomic) MyBlock backgroundURLSessionCompletionHandler in appDelegete; // method called at the end of the background request-(void) application :( UIApplication *) application handleEventsForBackgroundURLSession :( NSString *) identifier completionHandler :( void (^) () completionHandler {self. backgroundURLSessionCompletionHandler = completionHandler;} * // if it is a background NSURLSession, the background This method will be called after the request ends, notifying you That the UI should be updated if (session = [self backgroundSession]) {self. backgroundTask = nil; HMTAppDelegate * appDelegate = (HMTAppDelegate *) [UIApplication sharedApplication]. delegate; if (appDelegate. backgroundURLSessionCompletionHandler) {void (^ handler) () = appDelegate. backgroundURLSessionCompletionHandler; appDelegate. backgroundURLSessionCompletionHandler = nil; handler () ;}// the cache processing here is not good, You can process images in your own way, and the storage of images is subject to its own URL path, so there will be no repeated NSFileManager * fileManager = [NSFileManager defaultManager]; NSURL * cachesURLPath = [[fileManager URLsForDirectory: NSCachesDirectory inDomains: NSUserDomainMask] lastObject]; // obtain the downloaded file name based on the URL, the storage path (location is the directory of the downloaded temporary file, in the tmp folder) NSURL * destinationPath = [cachesURLPath URLByAppendingPathComponent: [location lastPathComponent]; NSError * error = nil; BOO L success = [fileManager moveItemAtURL: location toURL: destinationPath error: & error]; [fileManager removeItemAtURL: location error: NULL]; // location is the directory of the downloaded temporary file, copy the file from the temporary folder to the sandbox // BOOL success = [fileManager copyItemAtURL: location toURL: destinationPath error: & error]; if (success) {dispatch_async (dispatch_get_main_queue (), ^ {UIImage * image = [UIImage imageWithContentsOfFile: [destinationPath path]; se Lf. imageView. image = image; // UIImageView automatically crops the image to adapt to its frame. The following attribute shows the source image self. imageView. contentMode = UIViewContentModeScaleAspectFill;}) ;}// whether the task is successful or not, the proxy method-(void) URLSession :( NSURLSession *) session task (NSURLSessionTask *) will be called back after completion *) task didCompleteWithError :( NSError *) error {// if the error is nil, it indicates that the download is successful. Otherwise, you need to query the cause of the failure. If a part is downloaded, this error will contain an NSData object. if you want to resume the task later, you can use if (error = nil) {dispatch_async (dispatch_get_main_queue (), ^ {self. progressIndicator. hidden = YES;}) ;}}// Transfer Progress-(void) URLSession :( NSURLSession *) session downloadTask :( 0000*) downloadTask didWriteData :( int64_t) bytesWritten totalBytesWritten :( int64_t) totalBytesWritten totalBytesExpectedToWrite :( int64_t) totalBytesExpectedToWrite {dou Ble currentValue = totalBytesWritten/(double) totalBytesExpectedToWrite; dispatch_async (dispatch_get_main_queue (), ^ {NSLog (@ "% f", currentValue); self. progressIndicator. hidden = NO; self. progressIndicator. progress = currentValue;});} // unknown-(void) URLSession :( NSURLSession *) session downloadTask :( warn *) downloadTask didResumeAtOffset :( int64_t) fileOffset expectedTotalBytes :( int64 _ T) expectedTotalBytes {}# another important feature of pragma mark-NSURLSession: You can continue to transfer tasks even if the application is not in the foreground. Of course, our session mode should also be the backend mode-(NSURLSession *) backgroundSession {// the backend token passed to. We can only create one background session, so here we use dispatch once block static NSURLSession * backgroundSession = nil; static extends onceToken; dispatch_once (& onceToken, ^ {NSURLSessionConfiguration * config = [NSURLSessionConfiguration backgroundSessionConfiguration: @ "com. shinobicontrols. backgroundDownload. backgroundSession "]; backgroundSession = [NSURLSession sessionWithConfiguration: config delegate: self delegateQueue: nil];}); return backgroundSession;}-(void) didreceivemorywarning {[super success]; // Dispose of any resources that can be recreated .} /* # pragma mark-Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation-(void) prepareForSegue :( UIStoryboardSegue *) segue sender :( id) sender {// Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller .} * // @ end

@ Nice NSURLSession article
IOS 7 Series: Forget NSURLConnection and embrace NSURLSession!



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.