2015-06-22 29 views
0

我想在應用程序處於後臺模式時從我的應用程序上傳大文件(視頻)。我正在使用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]; 
+0

顯示您的代碼 – Wain

+0

最後我解決了問題。當我們嘗試將大文件上傳到服務器並且應用處於後臺狀態時,我們需要每60秒更新一次位置準確性。通過哪些應用程序不處於暫停狀態,並且在完成文件上傳後需要停止位置更新計時器時,我們可以將文件上傳到服務器。 –

回答

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並執行應用程序:handleEventsForBackgroundURLSession:completionHandler:在您的應用程序代理這樣當你的文件完全上傳時,系統會調用這個委託方法來喚醒你的應用程序。因此,您可以知道上傳過程已完成並可以執行任何其他任務。

您可以更好地瞭解如何使用NSURLSession和NSURLSessionConfiguration下載和上傳文件,同時該應用程序位於2鏈接以下的背景中,因此請參閱這些鏈接以實施它。

https://developer.apple.com/library/prerelease/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

http://w3facility.org/question/how-to-work-with-large-file-uploads-in-ios/

+0

嗨!這種方法有沒有時間限制?我想知道哪一個是最好的解決方案,這個方法和使用'beginBackgroundTaskWithExpirationHandler'方法的方法是一樣的。第二個給予「僅」180秒的額外時間。 – Zeb

+0

使用beginBackgroundTaskWithExpirationHandler:在後臺模式下上傳或下載大文件時更好。 – sajgan2015

+0

好的,但有沒有時間限制或完成? – Zeb

0

最後我用下面的代碼解決我的問題。把下面的鱈魚放在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];} 
相關問題