问题描述:

I have a View controller where I have a button which brings up the front camera. The user then takes a photo, the camera controller is dismissed and I show the picture taken in an Image View in the View Controller. Now, I start uploading the server to Amazon S3.

It does take some time for the uploading to complete and the user has to wait for that time before moving to the next view.

I would ideally like to move the user to the next view and let the uploading complete in the background. Is there some way I could do this uploading task in the background ? I know their is something called dispatch_queue which could be used to do this but I am not sure how. If I put the uploading code inside a queue in the view controller file and then move to the next view controller, will not the reference of the previous one be lost.

EDIT

I tried doing the following -

  1. Making a new class which would be responsible for uploading to Amazon S3.
  2. This new class is a delegate to AmazonServiceRequest which should be called when the uploading to Amazon S3 is complete.
  3. On completion uploading to S3, I make a call to my server to save the URL in the database.
  4. I make an object of this class inside the queue block like follows -

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);

dispatch_async(queue, ^{

RIDEUploadPhotoService *uploadPhotoServiceObj = [[RIDEUploadPhotoService alloc] init;

[uploadPhotoServiceObj uploadAndSaveImage:imageToSave];

});

It seems to me that the control never comes inside the request complete which should get called when uploading to Amazon S3 is complete.

网友答案:

Just use one of the asynchronous upload-mechanisms of NSURLConnection/NSURLSession, so you don't have to mess around with background threads. For example:

NSURL *fileURL = [NSURL fileURLWithPath:...];
NSURLRequest *request = [NSURLRequest requestWithURL:...];

// modern way: NSURLSession
NSURLSessionUploadTask *uploadTask = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromFile:fileURL completionHandler:...];
[uploadTask resume];

// old way: NSURLConnection 
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:...];

// another old way: synchronous NSURLRequest executed in a background queue
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSURLResponse *response;
    NSError *error;
    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
});
网友答案:

No. The reference will not be lost.

You can use - (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg to perform the method aSelector in the background. If you have any delegates after the completion of the task, they will still be called.

相关阅读:
Top