How to upload Big file(video) using AFNetworking while application is in Background mode?

1.9k views Asked by At

I want's to upload big file(video) from my application while application is in Background mode. I am using AFNetworking Library. Application is running from 3 min but after that it kill all the activity.

Below code i use in application.

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];
2

There are 2 answers

4
sajgan2015 On

For uploading large files you have to use AFURLSessionManager class and configure its object with NSURLSessionConfiguration.

Your code to upload large file using AFNetworking would be as following:

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 {

    }

   }];

You also have set the value of the NSURLSessionConfiguration object’s sessionSendsLaunchEvents property to YES and implement application:handleEventsForBackgroundURLSession:completionHandler: in your app delegate class so that when your file will be uploaded completely then the system will its call this delegate method to wake up your app. So you can know that the upload process is done and can perform any further task.

You can get better idea about using NSURLSession and NSURLSessionConfiguration to download and upload files while the app is in background from below 2 links so please refer these links to implement it.

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
Bhavesh Patel On

Finally i resolve my problem using below code. Put below cod in applicationDidEnterBackground. after file is uploading finish you need to stop location update and timer.

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];}