iOS AWS v2 S3传输管理器必须使用指定的端点

时间:2014-12-01 03:50:46

标签: ios amazon-web-services amazon-s3

我正在开发一个使用AWS作为其后端的iOS应用程序。由于我希望用户能够在全球范围内使用,因此我需要切换应用下载照片的位置,以提高延迟性能。我在EUWest1中创建了一个S3存储桶,在APNorthEast1中创建了另一个存储桶。正如Yosuke在此处所说(https://forums.aws.amazon.com/message.jspa?messageID=586581#586581),您可以将AWSServiceManager.defaultServiceManager()的默认配置从一个区域更改为另一个区域,以防止出错。

但是,即使我按照他的提示,我仍然有相同的错误结果。错误是:

  

错误Domain = com.amazonaws.AWSS3ErrorDomain Code = 0"操作无法完成。 (com.amazonaws.AWSS3ErrorDomain错误0。)" UserInfo = 0x14fb7720 {RequestId = D708XXX8E1EDBXXX,Endpoint = bucket-ap-northeast-1.s3-ap-northeast-1.amazonaws.com,Message =您尝试访问的存储区必须使用指定的端点进行寻址。请将以后的所有请求发送到此端点。,HostId = xxxY31S3yFhpssQe1EsfipWWLw =,Code = PermanentRedirect,Bucket = bucket-ap-northeast-1}

这是我的代码:

var credentialsProvider = AWSCognitoCredentialsProvider.credentialsWithRegionType(kCognitoRegionType, accountId: kAWSAccountID, identityPoolId: kCognitoPoolID, unauthRoleArn: kCognitoRoleUnauth, authRoleArn: kCognitoRoleAuth)
var serviceConfiguration = AWSServiceConfiguration(region: AWSRegionType.APNortheast1, credentialsProvider: credentialsProvider)
AWSServiceManager.defaultServiceManager().setDefaultServiceConfiguration(serviceConfiguration)
var transferManager = AWSS3TransferManager.defaultS3TransferManager()
transferManager.download(downloadRequest)

欢迎任何建议!谢谢!

3 个答案:

答案 0 :(得分:7)

最近才遇到同样的问题。 AWS SDK Docs非常令人困惑和矛盾,他们很糟糕......

上面的答案指出我正确的方向,因为我正在使用开发人员身份验证身份,我正在使用自定义身份提供程序(与github上的示例文档中的相同)。我将registerS3TransferManagerWithConfiguration与我的凭据提供程序一起使用,但随后提供了AWSRegionUSWest2作为密钥USWest2S3TransferManager的区域。

然后我在上传课程中调用了AWSS3TransferManager *transferManager = [AWSS3TransferManager S3TransferManagerForKey:@"USWest2S3TransferManager"];

希望这有助于其他人遇到类似问题。

- (AWSTask *)initializeClients:(NSDictionary *)logins {
    NSLog(@"initializing clients...");
    [AWSLogger defaultLogger].logLevel = AWSLogLevelVerbose;

    id<AWSCognitoIdentityProvider> identityProvider = [[DeveloperAuthenticatedIdentityProvider alloc] initWithRegionType:AWSRegionUSEast1
                                                                                                              identityId:nil
                                                                                                          identityPoolId:identityPoolID
                                                                                                                  logins:logins
                                                                                                            providerName:DeveloperAuthProviderName
                                                                                                              authClient:nil];

    self.credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionUSEast1
                                                                        identityProvider:identityProvider
                                                                           unauthRoleArn:nil
                                                                             authRoleArn:nil];


    AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:self.credentialsProvider];

    [AWSS3TransferManager registerS3TransferManagerWithConfiguration:[[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSWest2 credentialsProvider:self.credentialsProvider] forKey:@"USWest2S3TransferManager"];

    AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration;

    return [self.credentialsProvider getIdentityId];
}

我的具体上传方式:

- (void)performS3UploadWithRequest:(AWSS3TransferManagerUploadRequest *)request
{
    AWSS3TransferManager *transferManager = [AWSS3TransferManager S3TransferManagerForKey:@"USWest2S3TransferManager"];
    AWSTask *task = [AWSTask taskWithResult:nil];

    __weak typeof(self) weakSelf = self;
    task = [task continueWithSuccessBlock:^id(AWSTask *task) {
        return [[transferManager upload:request] continueWithBlock:^id(AWSTask *task) {
            if (task.error) {
                [self handleErrorWithTask:task request:request];
            }

            if (task.result) {
                AWSS3TransferManagerUploadOutput *uploadOutput = task.result;
                dispatch_async(dispatch_get_main_queue(), ^{
                    [weakSelf uploadProgress];
                });
                // The file uploaded successfully.
                DLog(@"%@", uploadOutput);
            }

            return nil;
        }];
    }];

    [task continueWithSuccessBlock:^id(AWSTask *task) {
        return nil;
    }];
}

答案 1 :(得分:5)

回答AWS v2

虽然您似乎使用代码中的区域正确设置了AWSServiceConfiguration,但您仍然使用默认的AWSS3TransferManagervar transferManager = AWSS3TransferManager.defaultS3TransferManager())。而是使用docs中指定的自定义init将传输管理器的配置设置为您已创建的serviceConfiguration


回答AWS v1

如果您创建的EUWest1和APNorthEast1等非美国标准的存储桶,则无法使用典型的路径式语法(“http://s3.amazonaws.com”或不需要指定的端点)来访问存储桶。

假设downloadRequestS3GetObjectRequest,在执行transferManager的下载之前,您应该设置S3GetObjectRequest的端点以匹配存储区域。

对于EUWest1,您可以将端点设置为:

[downloadRequest setEndpoint:@"s3-eu-west-1.amazonaws.com.com"];

对于APNorthEast1,您可以将端点设置为:

[downloadRequest setEndpoint:@"s3-ap-northeast-1.amazonaws.com"];

可以使用整个端点列表here

答案 2 :(得分:0)

每当亚马逊AWS Mobile SDK在控制台中显示不明确的警告时,请打开 verbose 日志记录进行调试:

(斯威夫特3) contains(QT,"core") { QMAKE_CXXFLAGS *= $$join(QMAKE_INCDIR_QT, " -isystem", "-isystem", "/QtCore") }
(斯威夫特2)AWSLogger.default().logLevel = .verbose

...以显示有关正在使用的S3存储桶,区域,端点等的更多信息。

我发现这对于在尝试在存储桶之间切换时发现正在发生什么特别有用,因为错误消息

  

... Endpoint = bucket-ap-northeast-1.s3-ap-northeast-1.amazonaws.com ,消息=您尝试访问的存储区必须使用进行寻址指定的端点。 ...

...没有提供有关实际/当前传输管理器配置的大量信息。