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

leo*_*ard 1 amazon-s3 amazon-web-services ios

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

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

Error Domain = com.amazonaws.AWSS3ErrorDomain Code = 0"无法完成操作.(com.amazonaws.AWSS3ErrorDomain error 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)
Run Code Online (Sandbox Code Playgroud)

欢迎任何建议!谢谢!

sud*_*udo 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];
}
Run Code Online (Sandbox Code Playgroud)

我的具体上传方法:

- (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;
    }];
}
Run Code Online (Sandbox Code Playgroud)


Lyn*_*ott 6

AWS v2的答案

虽然看起来好像是AWSServiceConfiguration在代码中使用区域正确设置,但仍然使用默认值AWSS3TransferManager(var transferManager = AWSS3TransferManager.defaultS3TransferManager()).而是使用文档中指定的自定义init 将传输管理器的配置设置为serviceConfiguration您已创建的配置.


AWS v1的答案

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

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

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

[downloadRequest setEndpoint:@"s3-eu-west-1.amazonaws.com.com"];
Run Code Online (Sandbox Code Playgroud)

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

[downloadRequest setEndpoint:@"s3-ap-northeast-1.amazonaws.com"];
Run Code Online (Sandbox Code Playgroud)

此处提供整个端点列表