4
votes

How do photo apps upload EVERYTHING from the CameraRoll in the background?

I have the need to upload 100s of photos in the background based on date range. My app is currently using NSURLSession with the following code (I think...) But for this to work, my task scheduler has to copy the JPG to a file in App storage (see: Background Upload With Stream Request Using NSUrlSession in iOS8) before the App goes into background. For 100s of photos this takes too much time and storage.

Is there a way to use a "streams" approach, or to reliably schedule additional NSURLSession tasks from the background? My developer says that CameraRoll photos that are potentially in iCloud would cause background scheduling to fail.

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didSendBodyData:(int64_t)bytesSent
totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend {
NSString *identifier = task.originalRequest.allHTTPHeaderFields[@"X-Image-Identifier"];

NSDictionary *d = [self sessionInfosDictionary];
NSURLSessionTaskInfo *info = d[identifier];
double p = (double)totalBytesSent/(double)totalBytesExpectedToSend;
info.progress = p;
[self saveSessionInfos:d];

for (id<PhotosUploaderDelegate>delegate in _delegates) {
    if ([delegate respondsToSelector:@selector(photoUploader:didUploadDataForAssetWithIdentifier:totalBytesSent:totalBytesExpectedToSend:)]) {
        [delegate photoUploader:self didUploadDataForAssetWithIdentifier:identifier totalBytesSent:totalBytesSent totalBytesExpectedToSend:totalBytesExpectedToSend];
    }
  }
}
2

2 Answers

1
votes

The task is not trivial, there is a lot of work to do.

Start from [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:] and +[NSURLSession uploadTaskWith...] methods.

You'll see that the tricky part is recovering from upload errors. You'll need to track each background upload in your application, by checking -[NSURLSession getTasksWithCompletionHandler:]. But first start from the beginning, with background session configurations and upload tasks.

1
votes

I haven't tried it but maybe you could copy the file and start a new upload task in the background session callback? This way you might be able to copy and upload the files one at a time.

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler {
   // copy file and schedule new upload task
}