• IOS网络访问之NSURLSession


    NSURLSession是IOS7中新添加的网络访问接口,作用与NSURLConnection一致,在程序在前台时,NSURLSession与NSURLConnection可以互为替代工作。如果用户强制将程序关闭,NSURLSession会断掉。

    NSURLSession中关键类有下面几种

    1:NSURLSessionConfiguration:用于配置NSURLSession工作模式以及网络设置

    工作模式分为下面三种:

    普通模式(default):可以使用缓存

    + (NSURLSessionConfiguration *)defaultSessionConfiguration; 

    瞬时模式(ephemeral):不使用缓存

    + (NSURLSessionConfiguration *)ephemeralSessionConfiguration; 

    后台模式(background):当按下home键后仍然可以在后台进行上传下载操作,需要通过唯一的identity标示

    + (NSURLSessionConfiguration *)backgroundSessionConfiguration:(NSString *)identifier; 

    网络设置:

    @property BOOL allowsCellularAccess   允许使用蜂窝数据

    @property (getter=isDiscretionary) BOOL discretionary  YES时表示任务后台运行时自动选择最佳的网络选择(综合考虑网络,电量)

    2:NSURLSession:获取NSURLSession有下面几种方式

    + (NSURLSession *)sharedSession  共享的会话,使用全局的Cookie,缓存数据

    + (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration  使用配置好的NSURLSessionConfiguration获得会话

    + (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(id <NSURLSessionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue  与第2中相似,但是指定了委托

    3:NSURLSessionTask:会话任务,通过NSURLSession创建,有下面3种常用子类

    NSURLSessionDataTask:最普通的网络访问,与NSURLConnection使用方式相似,多用来获取xml或者json,可以通过NSURLSession的以下方法创建

    - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;

    - (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url

    同时还可以通过block指定回调

    - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler; 

    - (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler; 

    NSURLSessionDownLoadTask:用来处理下载任务

    - (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;

    - (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url; 

    - (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData; 

    上面3种方法均可通过block设置回调,第三种方法可以实现断点续传

    NSURLSessionUploadTask:用来处理上传任务,NSURLSessionDataTask的子类

    - (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL

    - (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData

    - (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request

    上面3种方法同样可以通过block设置回调

    创建后的NSURLSessionTask需要调用resume才会执行

    4:NSURLSessionDelegate和NSURLSessionTaskDelegate协议

    在网络请求的各个阶段都会触发协议的不同方法,具体使用方法可以参照后面例子

    示例1:通过NSSessionDataTask访问网络数据

    -(void)viewDidLoad {
        [super viewDidLoad];
        
        NSString *urlStr = @"http://localhost/iostest.php";
        urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        
        //创建request
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr]];
        request.HTTPMethod = @"POST";
        request.HTTPBody = [@"name=zanglitao&gender=male" dataUsingEncoding:NSUTF8StringEncoding];
        
        //创建NSURLSession
        NSURLSession *session = [NSURLSession sharedSession];
        
        //创建任务
        NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }];
        
        //开始任务
        [task resume];
    }

    示例2:通过NSSessionUploadTask上传文件,流程和NSURLConnection基本一致,关键点也是设置请求头参数和请求体拼接

    //自定义一个boundary
    #define boundary @"zanglitao"
    @interface ZViewController()
    @end
    
    @implementation ZViewController
    
    -(void)viewDidLoad {
        [super viewDidLoad];
        
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://localhost/iostest.php"]];
        //必须使用POST
        request.HTTPMethod = @"POST";
        //设置请求体
        request.HTTPBody = [self getDataBody];
        //设置请求头
        [request setValue:[NSString stringWithFormat:@"%d",[self getDataBody].length] forHTTPHeaderField:@"Content-Length"];
        [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary] forHTTPHeaderField:@"Content-Type"];
        
        
        NSURLSession *session = [NSURLSession sharedSession];
        NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromData:[self getDataBody] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        }];
        
        [task resume];
    }
    
    //获取请求体内容
    -(NSData *)getDataBody {
        NSMutableData *data = [NSMutableData data];
        
        NSString *top = [NSString stringWithFormat:@"--%@
    Content-Disposition: form-data; name="file"; filename="1.png"
    Content-Type: image/png
    
    ",boundary];
        
        NSString *bottom = [NSString stringWithFormat:@"
    --%@--
    
    ",boundary];
        
        NSData *content = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"1" ofType:@"png"]];
        
        [data appendData:[top dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:content];
        [data appendData:[bottom dataUsingEncoding:NSUTF8StringEncoding]];
        return data;
    }
    
    @end

      

    示例3:使用NSURLSessionDownLoadTask下载文件

    -(void)viewDidLoad {
        [super viewDidLoad];
        
        NSURLSession *session = [NSURLSession sharedSession];
        
        NSURLSessionDownloadTask *task = [session downloadTaskWithURL:[NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/e61190ef76c6a7efc0a0e1ebfffaaf51f2de667c.jpg"] completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
           //下载完成后文件位于location处,我们需要移到沙盒中
            NSString *dirPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
            NSString *path = [dirPath stringByAppendingPathComponent:@"1.jpg"];
            
            NSFileManager *manager = [NSFileManager defaultManager];
            if ([manager fileExistsAtPath:path isDirectory:NO]) {
                [manager removeItemAtPath:path error:nil];
            }
            
            [manager moveItemAtPath:[location path] toPath:path error:nil];
            
        }];
        
        //开始任务
        [task resume];
    }

    执行后我们看到沙盒中多了一张名为1.jpg的图片,这是我们下载的图片

    上面的代码还有一点问题,就是下载过程中没有进度提示只能干等,我们可以通过设置委托获取下载进度

    示例4:使用委托查看下载进度

    @interface ZViewController()<NSURLSessionDelegate>
    @end
    
    @implementation ZViewController
    
    -(void)viewDidLoad {
        [super viewDidLoad];
        
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        
        //使用配置的NSURLSessionConfiguration获取NSSession,并且设置委托
        NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
        
        NSURLSessionDownloadTask *task = [session downloadTaskWithURL:[NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/e61190ef76c6a7efc0a0e1ebfffaaf51f2de667c.jpg"] ];
        
        //开始任务
        [task resume];
    }
    
    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
          didWriteData:(int64_t)bytesWritten
     totalBytesWritten:(int64_t)totalBytesWritten
    totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
        float percent = (float)totalBytesWritten/totalBytesExpectedToWrite;
        NSLog(@"%f",percent);
    }
    
    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
    didFinishDownloadingToURL:(NSURL *)location {
        NSString *dirPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
        NSString *path = [dirPath stringByAppendingPathComponent:@"1.jpg"];
        
        NSFileManager *manager = [NSFileManager defaultManager];
        if ([manager fileExistsAtPath:path isDirectory:NO]) {
            [manager removeItemAtPath:path error:nil];
        }
        [manager moveItemAtPath:[location path] toPath:path error:nil];
    }
    
    //任务结束
    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
    didCompleteWithError:(NSError *)error {
        NSLog(@"%s",__func__);
    }
    
    @end

    2014-11-08 14:11:44.146 IOS网络请求[2366:3507] 0.020172

    2014-11-08 14:11:44.147 IOS网络请求[2366:3507] 0.100307

    2014-11-08 14:11:44.148 IOS网络请求[2366:3507] 0.153730

    2014-11-08 14:11:44.148 IOS网络请求[2366:3507] 0.180442

    2014-11-08 14:11:44.149 IOS网络请求[2366:3507] 0.207153

    2014-11-08 14:11:44.150 IOS网络请求[2366:3507] 0.236461

    2014-11-08 14:11:44.156 IOS网络请求[2366:3507] 0.263173

    2014-11-08 14:11:44.160 IOS网络请求[2366:3507] 0.289884

    2014-11-08 14:11:44.160 IOS网络请求[2366:3507] 0.316596

    2014-11-08 14:11:44.161 IOS网络请求[2366:3507] 0.343307

    2014-11-08 14:11:44.162 IOS网络请求[2366:3507] 0.370019

    2014-11-08 14:11:44.162 IOS网络请求[2366:3507] 0.476865

    2014-11-08 14:11:44.163 IOS网络请求[2366:3507] 0.557000

    2014-11-08 14:11:44.169 IOS网络请求[2366:3803] 0.610423

    2014-11-08 14:11:44.170 IOS网络请求[2366:3803] 0.663846

    2014-11-08 14:11:44.171 IOS网络请求[2366:3803] 0.690558

    2014-11-08 14:11:44.175 IOS网络请求[2366:3803] 0.717269

    2014-11-08 14:11:44.176 IOS网络请求[2366:3803] 0.743981

    2014-11-08 14:11:44.176 IOS网络请求[2366:3803] 0.797404

    2014-11-08 14:11:44.177 IOS网络请求[2366:3803] 0.850827

    2014-11-08 14:11:44.178 IOS网络请求[2366:3803] 0.877539

    2014-11-08 14:11:44.179 IOS网络请求[2366:3803] 0.904250

    2014-11-08 14:11:44.180 IOS网络请求[2366:3803] 0.930962

    2014-11-08 14:11:44.180 IOS网络请求[2366:3803] 0.957674

    2014-11-08 14:11:44.180 IOS网络请求[2366:3803] 0.984385

    2014-11-08 14:11:44.181 IOS网络请求[2366:3803] 1.000000

    2014-11-08 14:11:44.182 IOS网络请求[2366:3803] -[ZViewController URLSession:task:didCompleteWithError:]

     

    下载是个漫长的过程,尤其是对于比较大的文件,所以我们还需要一个取消下载的按钮

    示例5:示例4添加取消下载功能

    @interface ZViewController()<NSURLSessionDelegate>
    @property(nonatomic,strong)NSURLSessionDownloadTask *task;
    
    @end
    
    @implementation ZViewController
    
    -(void)viewDidLoad {
        [super viewDidLoad];
        
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        
        //使用配置的NSURLSessionConfiguration获取NSSession,并且设置委托
        NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
        
        _task = [session downloadTaskWithURL:[NSURL URLWithString:@"http://yinyueshiting.baidu.com/data2/music/46729925/13125209147600128.mp3?xcode=10d30604371d01ea5cfa24abb2db23a644b52c81891b10c8"] ];
        
        //开始任务
        [_task resume];
    }
    
    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
          didWriteData:(int64_t)bytesWritten
     totalBytesWritten:(int64_t)totalBytesWritten
    totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
        float percent = (float)totalBytesWritten/totalBytesExpectedToWrite;
        NSLog(@"%f",percent);
    }
    
    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
    didFinishDownloadingToURL:(NSURL *)location {
        NSString *dirPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
        NSString *path = [dirPath stringByAppendingPathComponent:@"1.mp3"];
        
        NSFileManager *manager = [NSFileManager defaultManager];
        if ([manager fileExistsAtPath:path isDirectory:NO]) {
            [manager removeItemAtPath:path error:nil];
        }
        
        [manager moveItemAtPath:[location path] toPath:path error:nil];
    }
    
    //任务结束
    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
    didCompleteWithError:(NSError *)error {
        NSLog(@"%s",__func__);
    }
    
    - (IBAction)cancelDownload:(id)sender {
        [_task cancel];
    }
    
    @end

    2014-11-08 14:25:28.351 IOS网络请求[2451:3803] 0.000917

    2014-11-08 14:25:28.359 IOS网络请求[2451:3507] 0.008676

    2014-11-08 14:25:28.370 IOS网络请求[2451:1303] 0.010250

    2014-11-08 14:25:28.379 IOS网络请求[2451:5407] 0.018904

    2014-11-08 14:25:28.393 IOS网络请求[2451:3507] 0.022838

    2014-11-08 14:25:28.393 IOS网络请求[2451:3507] 0.023625

    2014-11-08 14:25:28.405 IOS网络请求[2451:3507] 0.030705

    2014-11-08 14:25:28.405 IOS网络请求[2451:3507] 0.034639

    2014-11-08 14:25:28.409 IOS网络请求[2451:1303] 0.035032

    2014-11-08 14:25:28.414 IOS网络请求[2451:5407] 0.035426

    2014-11-08 14:25:28.436 IOS网络请求[2451:3507] 0.035819

    2014-11-08 14:25:28.479 IOS网络请求[2451:3507] -[ZViewController URLSession:task:didCompleteWithError:]

    当按下取消按钮时下载停止,同时任务结束的方法被触发

    当然现实中更常见的方式是任务停止下载后还能恢复下载

    示例6:暂停与恢复

    - (IBAction)pauseDownload:(id)sender {
        [_task suspend];
    }
    
    - (IBAction)continueDownload:(id)sender {
        [_task resume];
    }

    有时候我们暂停了任务然后退出了程序,如果希望下次进入程序后还能继续下载,那就需要实现断点下载功能,在NSURLConnection中可以利用请求头的Range参数实现断点下载,在NSURLSession中实现断点下载更加简单

    示例7:断点下载

    @interface ZViewController()<NSURLSessionDelegate>
    
    @property (strong, nonatomic)NSURLSessionDownloadTask *task;
    //存储已下载的数据
    @property(nonatomic,strong)NSData *data;
    @end
    
    @implementation ZViewController
    
    -(void)viewDidLoad {
        [super viewDidLoad];
        
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        
        //使用配置的NSURLSessionConfiguration获取NSSession,并且设置委托
        NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
        _task = [session downloadTaskWithURL:[NSURL URLWithString:@"http://yinyueshiting.baidu.com/data2/music/46729925/13125209147600128.mp3?xcode=10d30604371d01ea5cfa24abb2db23a644b52c81891b10c8"] ];
        
        //开始任务
        [_task resume];
    }
    
    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
          didWriteData:(int64_t)bytesWritten
     totalBytesWritten:(int64_t)totalBytesWritten
    totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
        float percent = (float)totalBytesWritten/totalBytesExpectedToWrite;
        NSLog(@"%f",percent);
    }
    
    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
    didFinishDownloadingToURL:(NSURL *)location {
        NSString *dirPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
        NSString *path = [dirPath stringByAppendingPathComponent:@"1.mp3"];
        
        NSFileManager *manager = [NSFileManager defaultManager];
        if ([manager fileExistsAtPath:path isDirectory:NO]) {
            [manager removeItemAtPath:path error:nil];
        }
        
        [manager moveItemAtPath:[location path] toPath:path error:nil];
    }
    
    //任务结束
    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
    didCompleteWithError:(NSError *)error {
        NSLog(@"%s",__func__);
    }
    
    - (IBAction)pauseDownload:(id)sender {
        [_task cancelByProducingResumeData:^(NSData *resumeData) {
            _task = nil;
            _data = resumeData;
        }];
    }
    
    - (IBAction)continueDownload:(id)sender {
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
    
        _task = [session downloadTaskWithResumeData:_data];
        [_task resume];
    }
    
    @end

     

    示例8:后台下载

    @implementation ZViewController
    
    -(void)viewDidLoad {
        [super viewDidLoad];
        
        NSURLSession *session = [self session];
        NSURLSessionDownloadTask *task = [session downloadTaskWithURL:[NSURL URLWithString:@"http://yinyueshiting.baidu.com/data2/music/46729925/13125209147600128.mp3?xcode=10d30604371d01ea5cfa24abb2db23a644b52c81891b10c8"] ];
        
        //开始任务
        [task resume];
    }
    
    //后台会话(保证只有一个后台会话)
    -(NSURLSession *)session {
        static NSURLSession *session;
        static dispatch_once_t token;
        dispatch_once(&token, ^{
            
            //后台下载
            NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"zang"];
            configuration.discretionary = YES;
            
            //使用配置的NSURLSessionConfiguration获取NSSession,并且设置委托
            session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
        });
        
        return session;
    }
    
    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
          didWriteData:(int64_t)bytesWritten
     totalBytesWritten:(int64_t)totalBytesWritten
    totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
        float percent = (float)totalBytesWritten/totalBytesExpectedToWrite;
        NSLog(@"%f",percent);
    }
    
    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
    didFinishDownloadingToURL:(NSURL *)location {
        NSString *dirPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
        NSString *path = [dirPath stringByAppendingPathComponent:@"1.mp3"];
        
        NSFileManager *manager = [NSFileManager defaultManager];
        if ([manager fileExistsAtPath:path isDirectory:NO]) {
            [manager removeItemAtPath:path error:nil];
        }
        
        [manager moveItemAtPath:[location path] toPath:path error:nil];
    }
    
    
    
    //任务结束
    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
    didCompleteWithError:(NSError *)error {
        NSLog(@"%s",__func__);
    }
    @end

    启动程序后按下home键发现下载进度信息不再更新,静候片刻再进入程序发现沙盒中多了1.mp3,使用backgroundSessionConfiguration可以使我们的下载任务运行在后台

    我们也可以通过委托在文件下载完后进行界面更新

    示例9:后台下载任务监控

    当在后台下载完成后会触发AppDelegate的

    - (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler方法

    - (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {
        NSLog(@"%@:download complete",identifier);
       
        self.handler = completionHandler;
    }

    此方法包含一个competionHandler(此操作表示应用完成所有处理工作),通常我们会保存此对象;直到最后一个任务完成,此时会重新通过会话标识(上面sessionConfig中设置的)找到对应的会话并调用NSURLSession的-(void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session代理方法,在这个方法中通常可以进行UI更新,并调用completionHandler通知系统已经完成所有操作

    @implementation ZViewController
    
    -(void)viewDidLoad {
        [super viewDidLoad];
        
        NSURLSession *session = [self session];
        NSURLSessionDownloadTask *task = [session downloadTaskWithURL:[NSURL URLWithString:@"http://yinyueshiting.baidu.com/data2/music/46729925/13125209147600128.mp3?xcode=10d30604371d01ea5cfa24abb2db23a644b52c81891b10c8"] ];
        
        //开始任务
        [task resume];
    }
    
    //后台会话(保证只有一个后台会话)
    -(NSURLSession *)session {
        static NSURLSession *session;
        static dispatch_once_t token;
        dispatch_once(&token, ^{
            
            //后台下载
            NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"zang"];
            configuration.discretionary = YES;
            
            //使用配置的NSURLSessionConfiguration获取NSSession,并且设置委托
            session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
        });
        
        return session;
    }
    
    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
          didWriteData:(int64_t)bytesWritten
     totalBytesWritten:(int64_t)totalBytesWritten
    totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
        float percent = (float)totalBytesWritten/totalBytesExpectedToWrite;
        NSLog(@"%f",percent);
    }
    
    - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
    didFinishDownloadingToURL:(NSURL *)location {
        NSLog(@"%s",__func__);
        NSString *dirPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
        NSString *path = [dirPath stringByAppendingPathComponent:@"1.mp3"];
        
        NSFileManager *manager = [NSFileManager defaultManager];
        if ([manager fileExistsAtPath:path isDirectory:NO]) {
            [manager removeItemAtPath:path error:nil];
        }
        
        [manager moveItemAtPath:[location path] toPath:path error:nil];
    }
    
    //任务结束
    - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
    didCompleteWithError:(NSError *)error {
        NSLog(@"%s",__func__);
    }
    
    - (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
        NSLog(@"%s",__func__);
        
        ZLTAppDelegate *appDelegate = (ZLTAppDelegate *)[UIApplication sharedApplication].delegate;
        void(^handler)() = appDelegate.handler;
        appDelegate.handler = nil;
        handler();
    }
    
    @end

    2014-11-08 16:35:38.553 IOS网络请求[5149:1303] 0.018046

    2014-11-08 16:35:38.554 IOS网络请求[5149:1303] 0.018117

    2014-11-08 16:35:38.632 IOS网络请求[5149:3d07] 0.036427

    2014-11-08 16:35:38.633 IOS网络请求[5149:3d07] 0.036606

    2014-11-08 16:35:38.719 IOS网络请求[5149:4707] 0.054916

    2014-11-08 16:35:38.719 IOS网络请求[5149:4707] 0.055094

    2014-11-08 16:35:38.813 IOS网络请求[5149:1303] 0.073583

    2014-11-08 16:35:38.814 IOS网络请求[5149:1303] 0.092072

    2014-11-08 16:35:38.881 IOS网络请求[5149:3d07] 0.110560

    2014-11-08 16:35:46.697 IOS网络请求[5149:607] zang:download complete

    2014-11-08 16:35:46.701 IOS网络请求[5149:1303] -[ZViewController URLSession:downloadTask:didFinishDownloadingToURL:]

    2014-11-08 16:35:46.703 IOS网络请求[5149:1303] -[ZViewController URLSession:task:didCompleteWithError:]

    2014-11-08 16:35:46.703 IOS网络请求[5149:1303] -[ZViewController URLSessionDidFinishEventsForBackgroundURLSession:]

    执行程序后按下home键,静静等待下载完成后发现虽然程序处于后台,但委托的3个方法均得到了执行

  • 相关阅读:
    ABAP的HTTP_GET和Linux的curl
    SAP CRM点了附件的超链接后报错的处理方式
    一个JSON字符串和文件处理的命令行神器jq,windows和linux都可用
    如何在Ubuntu里安装Helm
    如何实现Windows宿主系统和虚拟机ubuntu系统文件互相访问
    如何安装Virtual Box的VBox Guest Additions扩展程序
    最简单的教程:在Ubuntu操作系统里安装Docker
    在ubuntun虚拟机里安装goLang语言编程环境
    hi35183e增加exfat文件系统的支持
    可以返回执行结果的system函数加强版本
  • 原文地址:https://www.cnblogs.com/zanglitao/p/4082334.html
Copyright © 2020-2023  润新知