AWS S3 上传适用于模拟器,但不适用于设备
AWS S3 Upload works on Simulator but not on Device
我遇到了一个有趣的问题。尝试将文件上传到 AWS S3,它在模拟器上 运行 时完美运行,在连接的设备上 运行 时也是如此(调试模式)。但是当我打包应用程序并将其部署到设备时,它不起作用。我不断收到 "Request Timed Out".
这是我的代码,
- (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;
}];
}
这是我得到的错误(混淆了敏感部分)-
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;
}
我不知道这里出了什么问题!非常感谢帮助。
当设备连接到 Xcode 时,我也得到了 URL 并通过 cURL 上传了文件。 FWIW,这也行!
折腾了2天,终于找到问题所在了!这是代码的一部分,我没有 post,但这是我初始化 AWS 客户端的方式。
AWSStaticCredentialsProvider *cp = [[AWSStaticCredentialsProvider alloc] initWithAccessKey:accesskey secretKey:secretKey];
AWSServiceConfiguration* config = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:cp];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = config;
现在,我正在使用另一个库,它做完全相同的事情,但对不同的存储桶使用不同的凭据。由于这个其他库是在我的代码之后被调用的,所以我在上传文件时遇到了问题。现在为什么错误是 Request Timed Out
而不是 Invalid Credentials
,我还没有找到。
我把初始化代码改成这个 --
AWSStaticCredentialsProvider *cp = [[AWSStaticCredentialsProvider alloc] initWithAccessKey:accesskey secretKey:secretKey];
AWSServiceConfiguration* config = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:cp];
[AWSS3TransferManager registerS3TransferManagerWithConfiguration:config forKey:AWSLogFilesUploaderKey];
并像这样获得了 AWSS3TransferManager
的实例 --
AWSS3TransferManager* tm = [AWSS3TransferManager S3TransferManagerForKey:AWSLogFilesUploaderKey];
然后一切顺利!
我遇到了一个有趣的问题。尝试将文件上传到 AWS S3,它在模拟器上 运行 时完美运行,在连接的设备上 运行 时也是如此(调试模式)。但是当我打包应用程序并将其部署到设备时,它不起作用。我不断收到 "Request Timed Out".
这是我的代码,
- (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;
}];
}
这是我得到的错误(混淆了敏感部分)-
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;
}
我不知道这里出了什么问题!非常感谢帮助。 当设备连接到 Xcode 时,我也得到了 URL 并通过 cURL 上传了文件。 FWIW,这也行!
折腾了2天,终于找到问题所在了!这是代码的一部分,我没有 post,但这是我初始化 AWS 客户端的方式。
AWSStaticCredentialsProvider *cp = [[AWSStaticCredentialsProvider alloc] initWithAccessKey:accesskey secretKey:secretKey];
AWSServiceConfiguration* config = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:cp];
AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = config;
现在,我正在使用另一个库,它做完全相同的事情,但对不同的存储桶使用不同的凭据。由于这个其他库是在我的代码之后被调用的,所以我在上传文件时遇到了问题。现在为什么错误是 Request Timed Out
而不是 Invalid Credentials
,我还没有找到。
我把初始化代码改成这个 --
AWSStaticCredentialsProvider *cp = [[AWSStaticCredentialsProvider alloc] initWithAccessKey:accesskey secretKey:secretKey];
AWSServiceConfiguration* config = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:cp];
[AWSS3TransferManager registerS3TransferManagerWithConfiguration:config forKey:AWSLogFilesUploaderKey];
并像这样获得了 AWSS3TransferManager
的实例 --
AWSS3TransferManager* tm = [AWSS3TransferManager S3TransferManagerForKey:AWSLogFilesUploaderKey];
然后一切顺利!