如何在应用程序处于后台模式时使用AFNetworking上传大文件(视频)?
我想在应用程序处于后台模式时从我的应用程序上传大文件(视频)。我正在使用AFNetworking库。应用程序从3分钟开始运行,但在此之后它会终止所有活动。如何在应用程序处于后台模式时使用AFNetworking上传大文件(视频)?
下面的代码我在应用程序中使用。
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {} failure:^(AFHTTPRequestOperation *operation, NSError *error) {}];
[operation setUploadProgressBlock:^(NSUInteger __unused bytesWritten,
long long totalBytesWritten,
long long totalBytesExpectedToWrite) {}];
[operation setShouldExecuteAsBackgroundTaskWithExpirationHandler:^{}];
[manager.operationQueue addOperation:operation];
对于上传大文件,您必须使用AFURLSessionManager类并使用NSURLSessionConfiguration配置其对象。
你的代码中使用AFNetworking将上传大文件如下:
NSString *appID = [[NSBundle mainBundle] bundleIdentifier];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:appID];
[manager setTaskDidSendBodyDataBlock:^(NSURLSession *session,NSURLSessionTask *task ,int64_t bytesSent, int64_t totalBytesSent,int64_t totalBytesExpectedToSend){
CGFloat progress = ((CGFloat)totalBytesSent/(CGFloat)sensize);
NSLog(@"Uploading files %lld -- > %lld",totalBytesSent,totalBytesExpectedToSend);
[self.delegate showingProgress:progress forIndex:ind];
}];
dataTask = [manager uploadTaskWithStreamedRequest:request progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
}
else {
}
}];
你也有NSURLSessionConfiguration对象的sessionSendsLaunchEvents属性的值设置为YES并执行应用程序:handleEventsForBackgroundURLSession:completionHandler:在您的应用程序代理这样当你的文件完全上传时,系统会调用这个委托方法来唤醒你的应用程序。因此,您可以知道上传过程已完成并可以执行任何其他任务。
您可以更好地了解如何使用NSURLSession和NSURLSessionConfiguration下载和上传文件,同时该应用程序位于2链接以下的背景中,因此请参阅这些链接以实施它。
http://w3facility.org/question/how-to-work-with-large-file-uploads-in-ios/
嗨!这种方法有没有时间限制?我想知道哪一个是最好的解决方案,这个方法和使用'beginBackgroundTaskWithExpirationHandler'方法的方法是一样的。第二个给予“仅”180秒的额外时间。 – Zeb
使用beginBackgroundTaskWithExpirationHandler:在后台模式下上传或下载大文件时更好。 – sajgan2015
好的,但有没有时间限制或完成? – Zeb
最后我用下面的代码解决我的问题。把下面的鳕鱼放在applicationDidEnterBackground。文件上传完成后,您需要停止位置更新和计时器。
if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]) { //Check if our iOS version supports multitasking I.E iOS 4
if ([[UIDevice currentDevice] isMultitaskingSupported]) { //Check if device supports mulitasking
UIApplication *application = [UIApplication sharedApplication]; //Get the shared application instance
__block UIBackgroundTaskIdentifier background_task; //Create a task object
background_task = [application beginBackgroundTaskWithExpirationHandler:^{
[application endBackgroundTask: background_task]; //Tell the system that we are done with the tasks
background_task = UIBackgroundTaskInvalid; //Set the task to be invalid
//System will be shutting down the app at any point in time now
}];
//Background tasks require you to use asyncrous tasks
if (videoManager.isUploading)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//Perform your tasks that your application requires
/*[application endBackgroundTask: background_task]; //End the task so the system knows that you are done with what you need to perform
background_task = UIBackgroundTaskInvalid; //Invalidate the background_task*/
if (self.locManager != nil)
{
[self.locManager stopUpdatingLocation];
[self.locManager stopMonitoringSignificantLocationChanges];
}
self.locManager = [[CLLocationManager alloc] init];
self.locManager.desiredAccuracy = kCLLocationAccuracyKilometer;
if (IS_OS_8_OR_LATER)
{
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined)
{
[self.locManager requestAlwaysAuthorization];
}
}
self.locManager.delegate = self;
[self.locManager setDistanceFilter:1000];
self.locManager.pausesLocationUpdatesAutomatically = NO;
[self.locManager startMonitoringSignificantLocationChanges];
[self.locManager startUpdatingLocation];
});
if (![timer isValid])
{
timer = [NSTimer scheduledTimerWithTimeInterval:60
target:self
selector:@selector(changeAccuracy)
userInfo:nil
repeats:YES];
}
}
else
{
[self.locManager stopUpdatingLocation];
[self.locManager stopMonitoringSignificantLocationChanges];
fromBackGround = false;
self.locManager.activityType = CLActivityTypeAutomotiveNavigation;
[self.locManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locManager setDistanceFilter:kCLDistanceFilterNone];
self.locManager.pausesLocationUpdatesAutomatically = NO;
[self.locManager startUpdatingLocation];
}
}
}
- (void) changeAccuracy{
[self.locManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locManager setDistanceFilter:900];}
显示您的代码 – Wain
最后我解决了问题。当我们尝试将大文件上传到服务器并且应用处于后台状态时,我们需要每60秒更新一次位置准确性。通过哪些应用程序不处于暂停状态,并且在完成文件上传后需要停止位置更新计时器时,我们可以将文件上传到服务器。 –