Beside the power, scalability and low cost of cloud computing, one of the most exciting aspects of Amazon Web Services is how easy is it to experiment with. At first the AWS console can look like daunting array of icons and services (SimpleElasticBeanFace…coming soon?) However, it’s much easier to play around with and learn than back in the days of running your own hardware servers. Plus there’s already a massive global infrastructure of data centers at your disposal!
Simple Storage Solution, S3, is a prefect starting point to get your feet wet (or should I say: head wet in the cloud). This blog will cover how to upload an image via the AWS console and download it using Swift in iOS. Even before delving into the AWS Swift SDK, downloading images/video/JSON from S3 into an app is quite straightforward.
In a future blog we’ll look at integrating the AWS SDK in Swift. So what is S3?..
S is for Size?
S3 boast unlimited only by your imagination…I mean it’s unlimited. So users of your app could hypothetically upload an unlimited number of images or video (tho this may end up being a bit pricey for you). You are limited to a single PUT operation being 5GB max, however it’s possible to have single objects up to 5TB.
S is for Speed?
- On PUTS: S3 offers read after write consistency. This means once a file has been uploaded to a bucket it’s near instantly available
- On overwrite PUTS and DELETES: S3 offers eventual consistency. This means if a file is updated or deleted it will take some time for that change to propagate through the network (but not long)
The objects in an S3 bucket are uploaded to a single AWS region (there are currently 13 across the world). Within that region the S3 data is stored redundantly at 2 or more data centers (aka AWS availability zones). So it makes sense to upload to a region closer to the majority of your users. When your app blows up like Pokemon Go… actually before that, it’s good to consider a couple of more advanced services that can super-charge your speeds.
- CloudFront – Instead of delivering S3 content from 1 region CloudFront allows you to utilize the Content Delivery Network of over 50 edge locations. The edge locations are essentially data centers that can cache data from S3 buckets closer to your users. If a user requests data that isn’t already cached at their closest edge location the edge location will retrieve it and store it in cache for a given TTL (time to live). It will then be faster to retrieve when the next user comes along. Even with the free tier AWS account you get 50GB of CloudFront transfer for a year.
- S3 Transfer Acceleration – for the upload side of things Transfer Acceleration can be turned on in the Properties tab of any S3 bucket. Like CloudFront it also uses the network of edge location but to increase the speed of uploads. There’s an amazing Speed Comparison Tool in the Transfer Acceleration tab that can give you some idea of the potential gains. There is a cost for boosting upload speed with Transfer Acceleration.
$3
A common theme through Amazon’s services is that you pay-for-what-you-use. There’s no minimum fee and it’s possible to do a lot on S3 with the free tier account. The current free limits are 5GB storage, 20,000 GETS, 2000 PUTS and 15GB of transfer out per month (for the first year). Above that the fees vary depending on the type of S3 storage (see below), but it’s all quite inexpensive and shouldn’t break the bank. The 3 factors that affect the costs are:
- Storage quantity
- Number of GET and PUT requests
- Quantity of data transferred
How to Download an Image from S3 using Swift
Step 1 – Create bucket
- From the AWS S3 console click “Create Bucket”
- The bucket will be given its own namespace so it has to be unique, all lowercase with no spaces.
- Choose a region where the bucket will be hosted. Choosing one closer to where most of your user are could help with latency.
Step 2 – Upload image
Once the bucket is created click upload and select a test photo to upload. Click “Set Details”. Here we’ll select Standard. If you’re curious here what all three options are:
- Standard – the option that’s probably best for most applications. It’s highly available. On S3 Standard Storage Amazonians claim 99.99% availability and 99.999999999% durability – meaning data corruption/lose are rather unlikely.
- Infrequently Accessed – optimized for older and less frequently accessed data. It does still have rapid access but there’s a small retrieval fee. In terms of running a mobile backend it may make sense to automatically transition old data to IA using the lifecycle management feature. At least from a cost perspective it might be worth thinking about if you have tons of user data + your AWS fees are getting up there.
- Reduced Redundancy Storage – essentially this is cheaper than standard storage but less reliable, only 99.99% durability. The use case for this would be if your app generates data that need to be stored in the cloud but could easily be reproduced, for example thumbnails for images in a social media app. If data loss occurred S3 could send a notification to your app (or backend workflow) which you’d use to trigger that data to be created again, in this case, making the thumbnail from the original photo.
We’ll leave the box for server-side encryption unchecked. However it is possible for Amazon to encrypt/decrypt the object as it’s written/read to disk at the data center using AES-256. Anyone with permission for the bucket is still going to be able to access it in the same way, whether it’s encrypted with SSE-S3 or not.
Step 3 – Click “Set Permissions”
Click “Set Permissions” and for this tutorial we’re going to select “Make everything public”. This allows the object in the bucket to be downloaded using https and the address name.
If you’re publish an app that uses S3 to the store, a more secure way of using S3 would be by authenticating your app with Amazon’s Cognito / Identity and Access Management so that only your app is granted access to the bucket. This will be covered in part 2!
Step 4 – Click “Upload”
Select the image and hit the properties tab. Your screen should look something like this:
Step 5 – Copy the link name
See where it says “Link”? Copy that long address.
Step 6 – Make a new Swift project
We’re going to make a download task to get our image from the S3 bucket. By default NSURLSession makes network calls in a background thread, hence it wont freeze the UI while the image is being downloaded.
Since iOS7 the recommended API for URL downloads has been NSURLSession.
Launch a new Swift single view application project for iPhone.
Step 7 – Unleash the Code Toad!
Here’s a basic example of how to programmatically create a UIImageView, download the image from S3 and add it to the main view. Change the view controller to:
import UIKit class ViewController: UIViewController { // link for your object on S3 let url = NSURL(string: "INSERT-YOUR-LINK-ADDRESS")! var imageView: UIImageView? override func viewDidLoad() { super.viewDidLoad() // initialize an image view let ivFrame = CGRect(x: 0, y: 0, width: 300, height: 200) imageView = UIImageView(frame: ivFrame) // download image from s3 let session = NSURLSession.sharedSession() let downloadTask = session.dataTaskWithURL(url) { data, response, error in if data == nil { print("\(error)") } else { // update the UI on the main queue dispatch_async(dispatch_get_main_queue()) { self.imageView!.image = UIImage(data: data!) self.imageView!.contentMode = UIViewContentMode.ScaleAspectFit self.view.addSubview(self.imageView!) } } } downloadTask.resume() } }
Find the Xcode project on GitHub here.
If you’ve found the post helpful please share with the links below!
I highly recommend the guys at A Cloud Guru as a resource to learn more about AWS.
For the latest updates + blog posts follow me on twitter here.