NSURLSession and amazon S3 uploads

后端 未结 7 1846
傲寒
傲寒 2020-12-12 21:27

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

7条回答
  •  温柔的废话
    2020-12-12 22:02

    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"

提交回复
热议问题