Search code examples
ios7nsurlsessionuploadtask

Upload photos in background in iPad using NSURLSession


What is the best method to upload multiple photos from the asset library using NSURLSessionUploadTask?

I'm now using NSURLSession background uploads. Here's the code I'm using:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0]; //getting path of documents directory.
    NSString *documentsPath = [documentsDirectory stringByAppendingPathComponent:@"tempFile.dat"];      //appending file name to documents path.

    ALAssetsLibraryAssetForURLResultBlock resultblock = ^(ALAsset *myasset)
    {
        ALAssetRepresentation *rep = [myasset defaultRepresentation];
        Byte *buffer = (Byte*)malloc(rep.size);
        NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:rep.size error:nil];
        NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];

        _totalBytesToSend += buffered;
        [_dataArray addObject:data];
    };

    ALAssetsLibraryAccessFailureBlock failureblock  = ^(NSError *myerror)
    {
        DLog(@"Can't get image - %@",[myerror localizedDescription]);
    };

    ALAssetsLibrary* assetslibrary = [[ALAssetsLibrary alloc] init];

    //work needed here
    for (NSURL *url in _urlArray) {

        if(url != nil)
        {
            [assetslibrary assetForURL:url
                           resultBlock:resultblock
                          failureBlock:failureblock];
        }

    }

    dispatch_async(dispatch_get_main_queue(), ^(void){
        for (NSData *data in _dataArray) {

            if(![data writeToFile:documentsPath atomically:YES])
            {
                DLog(@"Saving image failed");
            }

            //Prepare upload request
            NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"my url here"]];
            [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
            [request setHTTPMethod:@"POST"];
            [request addValue:[[DTETokenManager sharedManager] loginToken] forHTTPHeaderField: @"X-CSRF-Token"];

            _uploadTask = [_session uploadTaskWithRequest:request fromFile:[NSURL URLWithString:[NSString stringWithFormat:@"file://%@", documentsPath]]];
            [_uploadTask resume];
        }
    });

Is this a good approach? A problem I'm facing with this is that I'm not able to update a progress bar correctly, in which I intend to show the progress of the total upload process. I'm using the following code:

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
{

    //Progress reportpo
    _totalByteSent += totalBytesSent;
    if(_totalBytesToSend && _totalByteSent)
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:kBytesUploaded object:nil userInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithDouble:(double)totalBytesSent/(double)totalBytesExpectedToSend] forKey:NOTIFICATION_PAYLOAD]];
    }

}

As expected, the progress update is not at all proper :)

Please point out a better approach, as I'm finding it really difficult to find proper tutorials to handle uploads. There are plenty that explain background downloading though.


Solution

  • since i did not get any response from here , i ended up dumping the progress bar all together and adding an activity indicator which stops spinning when all downloads complete