1

I am trying to integrate both S3 and Mobile Analytics, using AWS iOS SDK v2, in my Swift project. The issue is that I am trying to use two different regions (I am working with my main region, eu-west-1 in Ireland, but Mobile Analytics is only available from us-east-1 in Virginia).

I have the following in my AppDelegate to initialize Mobile Analytics:

    let credentialsProviderForMobileAnalytics = AWSCognitoCredentialsProvider.credentialsWithRegionType(
        AWSRegionType.USEast1,
        accountId: "my_account_id",
        identityPoolId: "pool_id",
        unauthRoleArn: "XXX",
        authRoleArn: "XXX"
    )

    let awsConfigurationForMobileAnalytics = AWSServiceConfiguration(
        region: AWSRegionType.USEast1,
        credentialsProvider: credentialsProviderForMobileAnalytics
    )

    AWSServiceManager.defaultServiceManager().setDefaultServiceConfiguration(awsConfigurationForMobileAnalytics)
    var mobileAnalytics = AWSMobileAnalytics(forAppId: "MyAwsAppId")

Then, in a function called from a ViewController, where I want to upload an image to S3, I have:

    let credentialsProviderForS3 = AWSCognitoCredentialsProvider.credentialsWithRegionType(
        AWSRegionType.EUWest1,
        accountId: "my_account_id",
        identityPoolId: "pool_id",
        unauthRoleArn: "XXX",
        authRoleArn: "XXX"
    )

    let awsConfigurationForS3 = AWSServiceConfiguration(
        region: AWSRegionType.EUWest1,
        credentialsProvider: credentialsProviderForS3
    )

    AWSServiceManager.defaultServiceManager().setDefaultServiceConfiguration(awsConfigurationForS3)

    var transferManager = AWSS3TransferManager.defaultS3TransferManager()

    var fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory().stringByAppendingPathComponent("temp"))
    var uploadRequest1 : AWSS3TransferManagerUploadRequest = AWSS3TransferManagerUploadRequest()

        uploadRequest1.bucket = "mybucket"
        uploadRequest1.key =  "my-image.jpeg"
        uploadRequest1.body = fileURL
        var task = transferManager.upload(uploadRequest1)

If I comment one of the above two sections, the corresponding task gets completed perfectly (when the code for analytics is commented, s3 works and vice versa), but it won't work together - I suspect this is because I am setting the default service configuration using AWSServiceManager.defaultServiceManager().setDefaultServiceConfiguration() and the fact that I use two different regions somehow messes up everything. Either it refuses to log the events to Mobile Analytics, or it will interrupt the upload with the error message

NSUnderlyingError=0x17424ee20 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1001.)", NSErrorFailingURLKey=https://s3.amazonaws.com/mybucket/my-image.jpeg})

I tried setting the transfer manager for S3 like this (and commenting the setDefaultServiceConfiguration above):

    var transferManager = AWSS3TransferManager(configuration: awsConfigurationForS3, identifier: "S3")

which results in the following error during uploading:

"Error Domain=com.amazonaws.AWSS3ErrorDomain Code=0 \"The operation couldn\U2019t be completed. (com.amazonaws.AWSS3ErrorDomain error 0.)\" UserInfo=0x1742e7e00 {HostId=sm4qLUbN2XfkNYefbSU4A95UXTwvNYEBz0+bALqeFzlcXJ7rOGWnr1Yg+8HoU4r2, Bucket=mybucket, Endpoint=mybucket.s3.amazonaws.com, Message=The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint., Code=PermanentRedirect, RequestId=568728899BC328B0}"

I also tried passing "mybucket.s3.amazonaws.com" as bucket name, but this resulted in an error stating the bucket was not found.

I am really not sure what to try next. Hope you guys can give me some pointers on how to separate those two integrations, and get both working simultaneously.

Camillo
  • 544
  • 1
  • 6
  • 24
  • 1
    My next step would be setting up an S3 bucket in Virginia to see if the two work together if the location is the same. – MirekE Feb 25 '15 at 16:50
  • Hi @MirekE, thank you so much for your reply. I have created a separate bucket with a new cognito identity pool in us-east-1, and now it is working, as I expected. It is really not ideal that the bucket is located in us-east-1, because my whole setup is in eu-west-1, and all of our users are located in western europe. Do you have any idea how I can achieve having both mobile analytics and s3 in my preferred region that is not the same as for mobile analytics? Thanks again for your reply and your time ! – Camillo Feb 25 '15 at 18:35
  • 1
    Perhaps Amazon AWS support might help? – MirekE Feb 25 '15 at 19:49
  • I have posted this problem to AWS community forums: https://forums.aws.amazon.com/thread.jspa?messageID=604250 – Camillo Feb 25 '15 at 22:17

1 Answers1

2

The issue is that you are setting the S3 region to USEast1, yet your bucket is in EUWest1. Based on the log, you are setting USEast1 to the awsConfigurationForS3 object in the following code snippet:

var transferManager = AWSS3TransferManager(configuration: awsConfigurationForS3, identifier: "S3")

You should update the S3 region to EUWest1 (you can also update the Cognito Identity region to EUWest1 as well). Try the following code snippet:

// You can use the new constructor with fewer arguments.
let credentialsProviderForS3 = AWSCognitoCredentialsProvider.credentialsWithRegionType(
    AWSRegionType.EUWest1,
    identityPoolId: "pool_id"
)

let awsConfigurationForS3 = AWSServiceConfiguration(
    region: AWSRegionType.EUWest1,
    credentialsProvider: credentialsProviderForS3
)

// You need to retain a strong reference to an instance of AWSS3TransferManager until `- upload:` finishes executing. Making it a property is one way to do this.
self.transferManager = AWSS3TransferManager(configuration: awsConfigurationForS3, identifier: "S3")

var fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory().stringByAppendingPathComponent("temp"))
var uploadRequest1 : AWSS3TransferManagerUploadRequest = AWSS3TransferManagerUploadRequest()
uploadRequest1.bucket = "mybucket"
uploadRequest1.key =  "my-image.jpeg"
uploadRequest1.body = fileURL

// `- upload:` is an asynchronous request. This means you need to retain a strong reference to `transferManager` until the async call completes.
transferManager.upload(uploadRequest1)
Yosuke
  • 3,759
  • 1
  • 11
  • 21
  • Thanks a lot Yosuke, but as you can see in my second code snippet, it seems that the region is already set to `EUWest1`... What should I try next? Thanks in advance for your help! – Camillo Feb 25 '15 at 22:16
  • Hi Yosuke, thank you so much for your updated answer. It fixed my problem, I can now log analytics to USEast1 and use S3 in EUWest1 region at the same time. Thanks again, AWS rocks! :-) – Camillo Feb 26 '15 at 19:50