I have an app which is currently uploading images to amazon S3. I have been trying to switch it from using NSURLConnection to NSURLSession so that the uploads can continue w
I just spent sometime on that, and finally succeeded. The best way is to use AWS library to create the request with the signed headers and than copy the request. It is critical to copy the request since NSURLSessionTask would fail other wise. In the code example below I used AFNetworking and sub-classed AFHTTPSessionManager, but this code also works with NSURLSession.
@implementation MyAFHTTPSessionManager
{
}
static MyAFHTTPSessionManager *sessionManager = nil;
+ (instancetype)manager {
if (!sessionManager)
sessionManager = [[MyAFHTTPSessionManager alloc] init];
return sessionManager;
}
- (id)init {
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:toutBackgroundSessionNameAF];
sessionConfiguration.timeoutIntervalForRequest = 30;
sessionConfiguration.timeoutIntervalForResource = 300;
self = [super initWithSessionConfiguration:sessionConfiguration];
if (self)
{
}
return self;
}
- (NSURLSessionDataTask *)POSTDataToS3:(NSURL *)fromFile
Key:(NSString *)key
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{
S3PutObjectRequest *s3Request = [[S3PutObjectRequest alloc] initWithKey:key inBucket:_s3Bucket];
s3Request.cannedACL = [S3CannedACL publicReadWrite];
s3Request.securityToken = [CTUserDefaults awsS3SessionToken];
[s3Request configureURLRequest];
NSMutableURLRequest *request = [_s3Client signS3Request:s3Request];
// For some reason, the signed S3 request comes back with '(null)' as a host.
NSString *urlString = [NSString stringWithFormat:@"%@/%@/%@", _s3Client.endpoint, _s3Bucket, [key stringWithURLEncoding]] ;
request.URL = [NSURL URLWithString:urlString];
// Have to create a new request and copy all the headers otherwise the NSURLSessionDataTask will fail (since request get a pointer back to AmazonURLRequest which is a subclass of NSMutableURLRequest)
NSMutableURLRequest *request2 = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
[request2 setHTTPMethod:@"PUT"];
[request2 setAllHTTPHeaderFields:[request allHTTPHeaderFields]];
NSURLSessionDataTask *task = [self uploadTaskWithRequest:request2
fromFile:fromFile
progress:nil
completionHandler:completionHandler];
return task;
}
@end
Another good resource is the apple sample code hereand look for "Simple Background Transfer"