简体   繁体   中英

AWS S3 Upload works on Simulator but not on Device

I'm encountering an interesting problem. Trying to upload a file to AWS S3, it works perfectly when run on a simulator, also when run on a connected device (DEBUG mode). But when I package the app and deploy it to a device, it doesn't work. I keep getting "Request Timed Out".

This is my code,

- (void)uploadFileAtPath:(NSString *)filePath completionHandler:(void (^)(NSString *, NSError *))handler {
    NSString *fileName = [filePath lastPathComponent];
    AWSS3GetPreSignedURLRequest *getPreSignedURLRequest = [AWSS3GetPreSignedURLRequest new];
    getPreSignedURLRequest.bucket = self.bucketName;
    getPreSignedURLRequest.key = fileName;
    getPreSignedURLRequest.HTTPMethod = AWSHTTPMethodPUT;
    getPreSignedURLRequest.expires = [NSDate dateWithTimeIntervalSinceNow:3600];

    NSString *fileContentTypeStr = @"application/zip";
    getPreSignedURLRequest.contentType = fileContentTypeStr;

    [[[AWSS3PreSignedURLBuilder defaultS3PreSignedURLBuilder] getPreSignedURL:getPreSignedURLRequest]
     continueWithBlock:^id(AWSTask *task) {

         if (task.error) {
             NSLog(@"Error: %@",task.error);
         } else {

             NSURL *presignedURL = task.result;

             NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:presignedURL];
             request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
             [request setHTTPMethod:@"PUT"];
             [request setValue:fileContentTypeStr forHTTPHeaderField:@"Content-Type"];
             [request setHTTPBody:[NSData dataWithContentsOfFile:filePath]];

             NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration];
             NSURLSession * session = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:nil];

             NSURLSessionDataTask* uploadTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                 if (error) {
                     NSLog(@"URL Session Task Failed: %@", [error localizedDescription]);
                 }
                 else {
                     NSLog(@"URL Session Task Succeeded: HTTP %ld", ((NSHTTPURLResponse*)response).statusCode);

                 }
                 handler([[((NSHTTPURLResponse*)response).URL.absoluteString componentsSeparatedByString:@"?"] firstObject], error);

             }];
             [uploadTask resume];
         }

         return nil;
     }];
}

And this is the error I get (obfuscated sensitive parts) -

Error: The request timed out.,

UserInfo: {
   NSErrorFailingURLKey = "https://s3.amazonaws.com/bucketname/file-2-10-2015-10-13PM.zip?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIHY7KKHBLYOPMTPA%2F20151003%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20151003T051306Z&X-Amz-Expires=3599&X-Amz-SignedHeaders=content-type%3Bhost&X-Amz-Signature=504e1f5083116as09dc6a04c3b4152816a8d9e8bccff8f4ea0cbss9fcdc21eac";
   NSErrorFailingURLStringKey = "https://s3.amazonaws.com/bucketname/file-2-10-2015-10-13PM.zip?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIHY7KKHBLYOPMTPA%2F20151003%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20151003T051306Z&X-Amz-Expires=3599&X-Amz-SignedHeaders=content-type%3Bhost&X-Amz-Signature=504e1f5083116as09dc6a04c3b4152816a8d9e8bccff8f4ea0cbss9fcdc21eac";
   NSLocalizedDescription = "The request timed out.";
   NSUnderlyingError = "Error Domain=kCFErrorDomainCFNetwork Code=-1001 \"(null)\" UserInfo={_kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102}";
   "_kCFStreamErrorCodeKey" = "-2102";
   "_kCFStreamErrorDomainKey" = 4;
}

I have no idea what is going wrong here! Help much appreciated. While the device connected to Xcode, I also got the URL out and uploaded the file via cURL. FWIW, that works too!

After 2 days, I finally found the problem! This was the part of the code I did not post, but it is how I was initializing the AWS Client.

    AWSStaticCredentialsProvider *cp = [[AWSStaticCredentialsProvider alloc] initWithAccessKey:accesskey secretKey:secretKey];
    AWSServiceConfiguration* config = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:cp];
    AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = config;

Now, there was another library that I was using which did exactly the same thing, but with different credentials to a different bucket. Since this other library was getting called after my code, I was having problems with uploading the file. Now why was the error Request Timed Out instead of Invalid Credentials , is something I haven't found out yet.

I changed the initialization code to this --

    AWSStaticCredentialsProvider *cp = [[AWSStaticCredentialsProvider alloc] initWithAccessKey:accesskey secretKey:secretKey];
    AWSServiceConfiguration* config = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:cp];
    [AWSS3TransferManager registerS3TransferManagerWithConfiguration:config forKey:AWSLogFilesUploaderKey];

And obtained an instance of AWSS3TransferManager like this --

AWSS3TransferManager* tm = [AWSS3TransferManager S3TransferManagerForKey:AWSLogFilesUploaderKey];

And then everything went smooth!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM