How to use AWS iOS SDK to upload image from device and set to public

amazon-s3, file-upload, image, ios, permissions

Solution

To solve this problem, I started with Amazon's sample code in their iOS SDK, found here. In the SDK zip, the sample project of interest can be found at `samples/S3_Uploader`.

To get from that sample project to one in which the uploaded image is public, you simply need to add one line in the right place:

por.cannedACL   = [S3CannedACL publicRead];

where `por` is the `S3PutObjectRequest` used to upload the image.

My project's code for uploading looks like this (looks almost identical to Amazon's sample code):

NSString *uuid = @""; // Generate a UUID however you like, or use something else to name your image.
UIImage *image; // This is the UIImage you'd like to upload.

// This URL is not used in the example, but it points to the file
// to be uploaded.
NSString *url = [NSString pathWithComponents:@[ @"https://s3.amazonaws.com/", AWS_PICTURE_BUCKET, uuid ]];

// Convert the image to JPEG data. Use UIImagePNGRepresentation for pngs
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);

// Create the S3 Client.
AmazonS3Client *s3 = [[AmazonS3Client alloc] initWithAccessKey:AWS_ACCESS_KEY_ID withSecretKey:AWS_SECRET_KEY];

@try {
    // Create the picture bucket.
    [s3 createBucket:[[S3CreateBucketRequest alloc] initWithName:AWS_PICTURE_BUCKET]];

    // Upload image data.  Remember to set the content type.
    S3PutObjectRequest *por = [[S3PutObjectRequest alloc] initWithKey:uuid inBucket:AWS_PICTURE_BUCKET];
    por.contentType = @"image/jpeg"; // use "image/png" here if you are uploading a png
    por.cannedACL   = [S3CannedACL publicRead];
    por.data        = imageData;
    por.delegate    = self; // Don't need this line if you don't care about hearing a response.

    // Put the image data into the specified s3 bucket and object.
    [s3 putObject:por];
}
@catch (AmazonClientException *exception) {
    NSLog(@"exception");
}

`AWS_ACCESS_KEY_ID` and `AWS_SECRET_KEY` are, of course, your AWS credentials, and `AWS_PICTURE_BUCKET` is your picture bucket.

Problem

Since it seems we are limited to the number of buckets, I'm trying to figure out how to accomplish the following: - I have an iOS app, where users can upload a profile image. - Profile image can be viewed by anyone (I want it public). - Ideally, I can upload to a single bucket (for example: myprofilepics.s3.amazonaws.com) - Ideally, Each user can upload to their own sub folder (for example: myprofilepics.s3.amazonaws.com/images/userXXX/ - Ideally, I upload the image, and set it to public access direct from the app so that other users can immediately view profile pics. Am I missing something in the documentation? I appreciate any feedback on this issue.

Original source