Using AWS IoT with Amplify

The new Amplify Library for Swift (also known as v2) is implemented using the new AWS SDK for Swift, which is currently in Developer Preview and does not support AWS IoT .

Follow this guide if you are looking to:

  • Use AWS IoT for your Swift project using v2 of the Amplify Library for Swift
  • Migrate to v2 of the Amplify Library for Swift and you currently have an AWS IoT implementation in your project.

You can achieve it by using CocoaPods to pull the AWSIoT pod, and by manually providing the necessary credentials.

Prerequisites

You will need:

  1. CocoaPods installed in your computer.
  2. An application that is configured with the Auth category of the latest Amplify Library for Swift.

Installation

In a Terminal window, navigate to your application's root folder and run the following command:

1pod init

Open the resulting Podfile file and add the AWSIoT pod to your target

1platform :ios, '13.0'
2
3target :'YOUR-APP-NAME' do
4 use_frameworks!
5
6 pod 'AWSIoT'
7end

Go back to the Terminal and run:

1pod install

Now you can use the .xcworkspace file to open your application, and you should be able to successfully build and run it.

Configuration

In order to configure AWSIoTDataManager, you need to provide an instance that conforms to AWSCredentialsProvider.

Since your application is using Amplify Auth, you can use it to provide the credentials. Just create a new CredentialsProxy.swift file with the following content:

1import Amplify
2import AWSCognitoAuthPlugin
3import AWSCore
4import AWSPluginsCore
5import Foundation
6
7/// Convenience implementation of the aws-sdk-ios `AWSCredentialsProvider` protocol backed
8/// by Amplify's Cognito-based Auth plugin.
9///
10/// - Tag: CredentialsProxy
11class CredentialsProxy: NSObject {
12
13 /// - Tag: CredentialsProxyError
14 enum Error: Swift.Error {
15 case missingCredentialsProvider
16 case missingCognitoCredentials
17 }
18
19 private let auth: AuthCategoryBehavior
20
21 /// - Tag: CredentialsProxy.init
22 init(auth: AuthCategoryBehavior = Amplify.Auth) {
23 self.auth = auth
24 }
25
26 private func fetchCredentials() async throws -> AWSCore.AWSCredentials {
27 let session = try await auth.fetchAuthSession(options: nil)
28 guard let provider = session as? AuthAWSCredentialsProvider else {
29 throw Error.missingCredentialsProvider
30 }
31
32 let credentials = try provider.getAWSCredentials().get()
33 guard let cognitoCredentials = credentials as? AuthAWSCognitoCredentials else {
34 throw Error.missingCognitoCredentials
35 }
36
37 return AWSCredentials(
38 accessKey: cognitoCredentials.accessKeyId,
39 secretKey: cognitoCredentials.secretAccessKey,
40 sessionKey: cognitoCredentials.sessionToken,
41 expiration: cognitoCredentials.expiration
42 )
43 }
44}
45
46extension CredentialsProxy: AWSCore.AWSCredentialsProvider {
47
48 func credentials() -> AWSTask<AWSCore.AWSCredentials> {
49 let source = AWSTaskCompletionSource<AWSCore.AWSCredentials>()
50 Task {
51 do {
52 let credentials = try await fetchCredentials()
53 source.set(result: credentials)
54 } catch {
55 source.set(error: error)
56 }
57 }
58 return source.task
59 }
60
61 func invalidateCachedTemporaryCredentials() {}
62}

Add the corresponding import to the files in which you wish you use AWS IoT:

1import AWSIoT

You can then use a new CredentialsProxy instance as the credentials provider when creating your configuration with your unique client ID and endpoint:

1let iotEndPoint = AWSEndpoint(
2 urlString: "wss://xxxxxxxxxxxxx-ats.iot.<YOUR-AWS-REGION>.amazonaws.com/mqtt"
3)
4
5let iotDataConfiguration = AWSServiceConfiguration(
6 region: AWSRegionType.<YOUR-AWS-REGION>,
7 endpoint: iotEndPoint,
8 credentialsProvider: CredentialsProxy()
9)
10
11AWSIoTDataManager.register(with: iotDataConfiguration!, forKey: "MyAWSIoTDataManager")
12let iotDataManager = AWSIoTDataManager(forKey: "MyAWSIoTDataManager")

You can get the endpoint information from the IoT Core -> Settings page on the AWS Console.

Create IAM policies for AWS IoT

To use PubSub with AWS IoT, you will need to create the necessary IAM policies in the AWS IoT Console, and attach them to your Amazon Cognito Identity.

Go to IoT Core and choose Secure from the left navigation pane, and then Policies from the dropdown menu. Next, click Create. The following myIOTPolicy policy will allow full access to all the topics.

Attach your policy to your Amazon Cognito Identity

To attach the policy to your Cognito Identity, begin by retrieving the Cognito Identity Id from Amplify Auth.

Add the following import statements:

1import Amplify
2import AWSPluginsCore

Then you can retrieve the ID using Amplify.Auth.fetchAuthSession()

1let session = try await Amplify.Auth.fetchAuthSession()
2if let identityProvider = session as? AuthCognitoIdentityProvider {
3 let identityId = try identityProvider.getIdentityId().get()
4 print("Identity ID: \(identityId)")
5}

Finally, you need to attach the myIOTPolicy policy to the user's Cognito Identity Id with the following AWS CLI command:

1aws iot attach-principal-policy --policy-name 'myIOTPolicy' --principal '<YOUR_COGNITO_IDENTITY_ID>'