Using AWS SDK for iOS v2.0.6

The following should highlight the main points to start using the SDK to upload/download to an S3 instance through iOS.

import the following in the AppDelegate.h file:

#import <AWSiOSSDKv2/AWSCore.h>

import the followign were you need it:

#import <AWSiOSSDKv2/S3.h>

The new AWS SDK for iOS v2.0.6 is better structured than its predecessors with singleton instantiation and global configuration of the AWS service.

Before jumping into implementation, one should know the authentication process set up for the application. The implementation of the SDK may vary based on the authentication services used, however the concepts may be comprehended and generalized.

Basically, in order to communicate with an S3 instance one should present the right credentials. Uploading a file using the new SDK requires minimal setup and configuration. Simply, one needs to instantiate an object of class AWSS3TransferManagerUploadRequest, and pass this object a singleton instance of AWSS3TransferManager to submit the upload. This object can be created and configured as follows:

AWSS3TransferManagerUploadRequest *s3UploadRequest = [[AWSS3TransferManagerUploadRequest alloc] init];
s3UploadRequest.bucket = BUCKET_NAME;
s3UploadRequest.key = keyInBucket; // path of file inside the bucket
s3UploadRequest.contentType = @”image/jpeg”;
s3UploadRequest.body = profilePictureFileURL; // local temp NSURL

and then the upload method will look like this:

[[[AWSS3TransferManager defaultS3TransferManager] upload:s3UploadRequest] continueWithExecutor:[BFExecutor mainThreadExecutor] withBlock:^id(BFTask *task) {
if (task.error != nil) {
if( task.error.code != AWSS3TransferManagerErrorCancelled && task.error.code != AWSS3TransferManagerErrorPaused) {
[observer uploadingProfilePictureFailed];
}
} else {
[observer uploadingProfilePicutreSucceeful];
}
return nil;
}];

Wait!! Before you get too excited and go ahead and try out the code, AWS default service need to be set up and configured. Two things at least must be configured: AWS preferred region and AWS Credentials Provider. One can check the enum definition AWSRegionType found in AWSServiceEnum.h: (just mentioning it for the record, Xcode will most likely help with auto complete☺)

typedef NS_ENUM(NSInteger, AWSRegionType) {
AWSRegionUnknown,
AWSRegionUSEast1,
AWSRegionUSWest1,
AWSRegionEUWest1,
AWSRegionAPSoutheast1,
AWSRegionAPNortheast1,
AWSRegionUSWest2,
AWSRegionSAEast1,
AWSRegionAPSoutheast2,
AWSRegionCNNorth1,
};

Credential Provider:

The simplest configuration of AWS service requires the referencing an object to be the credentials provider for the service. This object is either an instance of one of the credentials providers defined by the SDK (listed below), or an instance of a class that conforms with the protocol AWSCredentialsProvider.

Here is the list of predefined credentials providers:

@interface AWSStaticCredentialsProvider : NSObject <AWSCredentialsProvider>
@interface AWSAnonymousCredentialsProvider : NSObject <AWSCredentialsProvider> // empty implementation
@interface AWSWebIdentityCredentialsProvider : NSObject <AWSCredentialsProvider>
@interface AWSCognitoCredentialsProvider : NSObject <AWSCredentialsProvider>

The protocol defines three properties that will hold the credentials, and one method that will be called to refresh credentials. The protocol definition is as follows:

@class BFTask;
@protocol AWSCredentialsProvider <NSObject>
@optional
@property (nonatomic, strong, readonly) NSString *accessKey;
@property (nonatomic, strong, readonly) NSString *secretKey;
@property (nonatomic, strong, readonly) NSString *sessionKey;
@property (nonatomic, strong, readonly) NSDate *expiration;
- (BFTask *)refresh;
@end

An upload request (or any other request that takes place through the SDK) will invoke the refresh method in the AWSCredentialsProvider protocol, this method should invoke a request to an authentication server and then update the protocol’s properties with values received from authentication server. The predefined credentials prover classes do fully implement this method, however if one decides to use an instance of a custom class that conforms with the protocol, this method should be implemented.

Cons:

The drawback of the current credentials handling in the SDK is that it does not allow for a high level of granularity, and it is best described with an example. The method refresh is called without giving the option to specify HTTP request method to be used. The authentication sever may be set to provide a different token deepening on the HTTP method that will consume this token (PUT, GET, … etc).

The good thing though is that this refresh method is not @required. A good workaround is to have custom methods to retrieve credentials from authentication server depending on the HTTP method intended to be used, and then call the upload/download request in a completion block. For example:

[self requestS3CredentialsForUploadingWithCompletionHandler:^(BOOL finished) {
[self uploadProfilePictureToS3ForUserWithUserId:userId];
}];
Show your support

Clapping shows how much you appreciated Muhammad Arafat’s story.