0

我想在应用程序处于后台模式时从我的应用程序上传大文件(视频)。我正在使用 AFNetworking 库。应用程序从 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];
4

2 回答 2

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 并在您的应用委托类中实现 application:handleEventsForBackgroundURLSession:completionHandler: 以便当您的文件完全上传时,系统将调用此委托方法来唤醒您的应用. 因此,您可以知道上传过程已完成并且可以执行任何进一步的任务。

您可以通过以下 2 个链接更好地了解如何在应用程序处于后台时使用 NSURLSession 和 NSURLSessionConfiguration 下载和上传文件,因此请参考这些链接来实现它。

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/

于 2015-06-22T10:19:18.507 回答
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];}
于 2016-09-21T12:06:16.100 回答