我希望在应用程序处于后台模式时从我的应用程序上传大文件(视频)。我正在使用AFNetworking Library。应用程序从3分钟开始运行,但之后会终止所有活动。
我在应用程序中使用的代码。
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];
答案 0 :(得分:0)
要上传大文件,您必须使用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,并在您的app委托类中实现application:handleEventsForBackgroundURLSession:completionHandler:这样当您的文件完全上传时,系统将调用此委托方法来唤醒你的应用程序。因此,您可以知道上传过程已完成,可以执行任何进一步的任务。
您可以更好地了解如何使用NSURLSession和NSURLSessionConfiguration下载和上传文件,同时应用程序位于后面2个链接的后台,所以请参考这些链接来实现它。
http://w3facility.org/question/how-to-work-with-large-file-uploads-in-ios/
答案 1 :(得分:0)
最后,我使用下面的代码解决了我的问题。将下面的cod放在 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];}