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:@"--%@\nContent-Disposition: form-data; name=\"file\"; filename=\"1.png\"\nContent-Type: image/png\n\n",boundary];
    
    NSString *bottom = [NSString stringWithFormat:@"\n--%@--\n\n",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個方法均得到了執行


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM