链接背景NSURLSession上传 [英] Chaining background NSURLSession uploads

查看:92
本文介绍了链接背景NSURLSession上传的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人成功链接了NSURLSession后台上传吗?

Has anyone been successful in chaining NSURLSession background uploads?

我正尝试使用NSURLSession的后台上传功能以5 MB的部分上传一个巨大的视频文件。上传必须井井有条。整个事情在前台工作正常。我正在为此使用AFNetwoking及其分段上传。但是,当应用程序在后台运行时,第一个项目可以正常上传,并在后台启动第二个项目(在AFURLSessionManager的setDidFinishEventsForBackgroundURLSessionBlock中)。但是它突然停止了(我最好的猜测是在30秒内,因为在后台唤醒的应用程序的最长使用时间为30秒),然后什么也没有发生。我希望第二个会话将在后台完成,并调用第三个会话-连锁行为,但这似乎行不通。

I am trying to upload a huge video file in 5 MB parts using background upload of NSURLSession. The uploads has to be in order. The whole thing works fine in foreground. I am using AFNetwoking for this, and its a multi part upload. But when the app is in background, the first item uploads fine and starts the second one in background (in setDidFinishEventsForBackgroundURLSessionBlock of AFURLSessionManager). But it stops abruptly (my best guess is in 30 seconds, as an app woken up in background has a max lifetime of 30 sec) and then nothing happens. I expected the second session will finish in background and call up the third etc - a chain behaviour, but this just does not seem to work.

我尝试添加所有文件使用HTTPMaximumConnectionsPerHost = 1一次性将多个部分合并到一个NSURLSession中-这可以正常工作,并按部分上传完整文件。但是文件部分是按随机顺序选择的,即部分1被上传,然后部分5,部分3,部分10等等。我尝试将其添加到具有操作之间依赖性的NSOperationQueue中,这似乎使整个事情搞砸了-上传根本不起作用。

I have tried adding all file parts to a single NSURLSession in one go with a HTTPMaximumConnectionsPerHost = 1 - this works fine and uploads the full file in parts. But the file parts are picked in random order, i.e. part 1 gets uploaded, then part 5, part 3, part 10 etc …. I tried adding this in an NSOperationQueue with dependency between operations and this seems to mess up the entire thing - the upload does not work at all.

我知道视频文件可以在后台作为单个文件上传,但是服务器希望以5 MB的部分上传。因此,我想我唯一的选择是链式上传,或将所有部分添加到NSURLSession中,但要确保始终按添加顺序上传它们。

I know that the video file can be uploaded as a single file in background, but the server expects this in 5 MB parts. Hence I guess my only option is to chain uploads, or add all the parts to a NSURLSession, but make sure they are always uploaded in the order they are added.

任何

我的代码:

 - (void)viewDidLoad {

    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:[NSString stringWithFormat:@"%d", rand()]];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:config];
    config.HTTPMaximumConnectionsPerHost = 1;
    [manager setDidFinishEventsForBackgroundURLSessionBlock:^(NSURLSession *session) {

        dispatch_async(dispatch_get_main_queue(), ^{
            // Call the completion handler to tell the system that there are no other background transfers.
            //                completionHandler();
            [self upload];
        });
    }];
}

- (IBAction)start:(id)sender {

    [self upload];
}

-(void) upload {

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Sample" ofType:@"mp4"];
    AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];

    NSDictionary *parameters = [NSDictionary dictionaryWithObjectsAndKeys:@"234", @"u", @"Sample.mp4", @"f",nil];
    NSMutableURLRequest *request = [serializer multipartFormRequestWithMethod:@"POST" URLString:urlString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileURL:[NSURL fileURLWithPath:filePath] name:@"data" fileName:@"Sample.mp4" mimeType:@"video/mp4" error:nil];
    } error:nil];


    __block NSString *tempMultipartFile = [NSTemporaryDirectory() stringByAppendingPathComponent:@"Test"];
    tempMultipartFile = [tempMultipartFile stringByAppendingString:[NSString stringWithFormat:@"%d", rand()]];
    NSURL *filePathtemp = [NSURL fileURLWithPath:tempMultipartFile];
    __block NSProgress *progress = nil;
    [serializer requestWithMultipartFormRequest:request writingStreamContentsToFile:filePathtemp completionHandler:^(NSError *error) {
        NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePathtemp progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {

            NSLog(@"Request--> %@.\n Response --> %@ \n%@",  request.URL.absoluteString ,responseObject, error? [NSString stringWithFormat:@" with error: %@", [error localizedDescription]] : @""); //Lets us know the result including failures
            [[NSFileManager defaultManager] removeItemAtPath:tempMultipartFile error:nil];

        }];
        [uploadTask resume];
        [manager setTaskDidSendBodyDataBlock:^(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {

            NSLog(@"uploading");
        }];
    }];
}


推荐答案

好吧,最后我伸出援手向苹果寻求有关链接后台上传的说明-在iOS中无法实现。NSURLSession具有恢复速率限制器,可防止应用程序在后台执行链接任务,如 https://forums.developer.apple.com/thread/14854 。相反,苹果建议批量转移或其他选项,例如 https://forums.developer.apple.com/线程/ 14853 。我要问的另一件事是在上传队列中对多个任务进行排序-即,强制NSURLSession以添加任务的顺序来上传任务。正如 dgatwood 所指出的那样,不可能使用NSOperationQueue,Apple也提到了这一点。 https://forums.developer.apple.com/people/eskimo rel = nofollow noreferrer> eskimo 回复邮件 NSURLSession不能保证按顺序运行您的请求,因此无法强制执行。 因此,我在最初的问题上几乎没有其他选择。

Well, finally I reached out to Apple for clarifications on chaining background uploads - This is not possible in iOS.NSURLSession has a Resume Rate Limiter which prevents apps from executing chained tasks in background as explained in https://forums.developer.apple.com/thread/14854. Instead, apple suggests batch transfers or other options like https://forums.developer.apple.com/thread/14853. The other thing I was asking was to order the multiple tasks in upload queue - i.e, force NSURLSession to upload tasks in the order in which they are added. As pointed by dgatwood, using an NSOperationQueue is not possible and Apple also mentioned the same.As mentioned by eskimo in response mail "NSURLSession does not guarantee to run your requests in order and there’s no way to enforce that." So I am pretty much left option less on my original problem.

这篇关于链接背景NSURLSession上传的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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