objective-c - iOS能否在后台开始上传?

查看:252
本文介绍了objective-c - iOS能否在后台开始上传?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

百度云盘的那种自动上传用户相册中的图片。

我想请问,如果在应用前台没有启动上传操作(就是说应用在前台活跃时我并没有启动这个上传操作),能否在后台进行启动,并完成上传操作呢?

因为我看到nsurlsession提供了应用进入后台可继续已经开始的上传下载的操作,但不知道能否行得通进入后台智斗再开始上传及下载的操作,求解惑

解决方案

可以的

官方文档:NSURLSessionUploadTask

Note
Unlike data tasks, you can use upload tasks to upload content in the background. (For details, see URL Session Programming Guide.)

这里的意思大概是:你如果上传的是file而不是data, 就可以在后台进行上传。
对应的两个创建NSURLSessionUploadTask的函数:

/* Creates an upload task with the given request.  The body of the request will be created from the file referenced by fileURL */
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;

/* Creates an upload task with the given request.  The body of the request is provided from the bodyData. */
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData;

下面是我用来上传下载文件的代码,我用了AFNetworking

/**
 从指定url下载文件至指定path(忽略存在的)
 */
+(void)downloadFromUrl:(NSString *)url toLocalPath:(NSString *)path identifier:(NSString *)identifier progress:(void (^)(NSProgress *progress))downloadProgressBlock completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    
    if(![fileManager fileExistsAtPath:path]) {
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:identifier];
        AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
        NSURL *URL = [NSURL URLWithString:url];
        NSURLRequest *request = [NSURLRequest requestWithURL:URL];
        
        // 非主线程中执行
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
                // 主线程中执行
                dispatch_async(dispatch_get_main_queue(), ^{
                    downloadProgressBlock(downloadProgress);
                });
            } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
                return [NSURL fileURLWithPath:path];
            } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
                NSLog(@"File downloaded to: %@", filePath);
                
                // 主线程中执行
                dispatch_async(dispatch_get_main_queue(), ^{
                    completionHandler(response, filePath, error);
                });
            }];
            [downloadTask resume];
        });
    }
    else {
        dispatch_async(dispatch_get_main_queue(), ^{
            completionHandler(nil, nil, nil);
        });
    }
}

/**
 用于上传分片数据
 */
+(void)upload:(NSString *)urlString identifier:(NSString *)identifier progress:(void (^)(NSProgress *uploadProgress))uploadProgressBlock data:(NSData *)data completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError * error))completionHandler {
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
    [request addValue:@"binary/octet-stream" forHTTPHeaderField:@"content-type"];
    [request setHTTPMethod:@"PUT"];
    [request setTimeoutInterval:120];
    [request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
    
    // 非主线程中执行
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //fromData不能用于background, 要支持background上传用fromFile
        NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromData:data progress:^(NSProgress * _Nonnull uploadProgress) {
            // 主线程中执行
            dispatch_async(dispatch_get_main_queue(), ^{
                uploadProgressBlock(uploadProgress);
            });
        } completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
            // 主线程中执行
            dispatch_async(dispatch_get_main_queue(), ^{
                completionHandler(response, responseObject, error);
            });
        }];
        
        [uploadTask resume];
    });
}

这篇关于objective-c - iOS能否在后台开始上传?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆