有人成功链接 NSURLSession 后台上传吗?
我正在尝试使用 NSURLSession 的后台上传来上传 5 MB 的巨大视频文件。上传必须按顺序进行。整个事情在前台工作得很好。我为此使用 AFNetwoking,它是多部分上传。但是,当应用程序处于后台时,第一个项目上传正常,并在后台启动第二个项目(在 AFURLSessionManager 的 setDidFinishEventsForBackgroundURLSessionBlock 中)。但它突然停止(我最好的猜测是 30 秒内,因为在后台唤醒的应用程序的最大生命周期为 30 秒),然后什么也没有发生。我预计第二个会话将在后台完成并调用第三个会话等 - 连锁行为,但这似乎不起作用。
我尝试使用 HTTPMaximumConnectionsPerHost = 1 将所有文件部分一次性添加到单个 NSURLSession - 这工作正常并分部分上传完整文件。但文件部分是按随机顺序选取的,即上传第 1 部分,然后上传第 5 部分、第 3 部分、第 10 部分等……。我尝试将其添加到 NSOperationQueue 中,并在操作之间具有依赖关系,这似乎弄乱了整个事情 - 上传根本不起作用。
我知道视频文件可以在后台作为单个文件上传,但服务器期望该文件大小为 5 MB。因此,我想我唯一的选择是链接上传,或者将所有部分添加到 NSURLSession 中,但确保它们始终按照添加顺序上传。
任何帮助,将不胜感激。
My code:
- (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");
}];
}];
}