For TenStats, I had to upload video file which were about 300 to 400 MB to S3. As you can imagine it can take some time. iOS has some nice features allowing to do networking in the background, be it downloading or uploading, so I was hopeful.

Then I discovered the AWS Transfer Utility and was thrilled. It was working great, with one big exception... If the upload took more than an hour, the upload would fail. And I did not find out because I ran into the issue myself, but because my users did. They were using the app in real life and the real world does not always include a nice stable WIFI connection...

So after digging around a little bit I found that AWS Transfer Utility uses Cognito identity to create temporary credentials which allow you to upload the file. Those credentials have a limited lifespan of 60 minutes.

From there, I essentially found out that if I wanted to upload a large file in the background to AWS S3 reliably, I needed to roll up my sleeves and do some dirty work. To keep this short, I'll omit the NSURLSession background code for now as it adds another layer of complexity. I'll keep that for another post.

Overview

If you work with AWS framework, you probably know this, but it is in my opinion a very verbose framework. What I mean by this is that you have to go through multiple small steps to get it to work.

For example, if you want to upload a file you'll need to:

Configure the AWS Framework

create a request to tell AWS you are creating a multipart upload

run the request you just created

Create a request to ask AWS for a pre-signed URL for each part

Run the request you just created

upload each part to the pre-signed URL you got

Create a request to tell AWS that you uploaded everything

Run the request you just created

Yes, that is a lot of step, I guess for simpler scenario you can use the AWS Transfer Utility...

Configure AWS

First the AWS framework needs to be configured to be able to generate pre-signed URLs which are valid for more than 60 minutes. The official way of doing this is to do it on your servers. I did not have any servers available to do this and I was actually doing a proof of concept, so I generated those links in the app.