How to Connect an iOS App to AWS IoT
Josh PerryJosh Perry
This post describes how to connect an iOS app via MQTT (websocket) to AWS IoT, without requiring users to be authenticated with AWS Cognito, generating unique X.509 certificates in each distribution of the app or using AWS Amplify. This article presents a quick, lightweight solution.
Quick disclaimer: Those that follow me for motivational content, this isn’t it, unless coding leaves you inspired. 😉 This post is about software development.
As far as I’m aware, there are two other methods of achieving this that cater to different Applications. They are:
The above methods did not match my requirements which were characterized by the following:
So, if your Applications is similar to mine, read on to find out how to connect your iOS app to AWS IoT quickly and simply.
|| #IoTForAll #IoT " quote="Want to connect your iOS app to AWS IoT? You can connect an iOS app via MQTT (websocket) to AWS IoT without requiring users to be authenticated with AWS Cognito using AWS Amplify." theme="]
Follow these steps to create a Cognito Identity Pool:
The only two informational pieces you’ll need from this process are:
aws-region:uuid
(where uuid = 36 character unique identifierThe Identity Pool ID can be copied from the sample code, as can the region, as a typedef from the AWSCore module.
Now we need to give our Identity Pool permission to access IoT core.
A quick note on AWS IAM (Identity and Access Management) for anyone who is new/confused. Here’s a serious, but useful oversimplification: there are two fundamental concepts:
Think of a role as a person who has a specific job, i.e. a cook who’s in charge of dicing onions. Each role carries an "access card’" with a list of privileges on it. Think of a chopping policy as a line item on the card that allows them access to (a) a sharp knife and (b) a chopping board. Here are the docs from AWS.
Head over to IAM in the AWS console and follow these steps to add IoT access:
Cognito_YourPoolNameAuth_Role
and Cognito_YourPoolNameUnauth_Role
Connecting an iOS app the AWS IoT requires the following:
I really like Cocoapods as a dependency manager for iOS, and, if you're unaware, I highly recommend checking it out.
If you have Cocoapods installed, add:pod 'AWSIoT’
(this will automatically add AWSCore as it’s required by AWSIoT) and $ pod install
to update your dependencies.
Obviously, use the dependency manager you prefer. Explaining the function of these is outside the scope of this article.
In whichever class or file you want to write your IoT interfacing code, import the AWSIoT module:
import AWSIoT
The following piece of code will generate credentials used to initialize the AWSIoTDataManager:
Earlier you made a note of your Identity Pool ID and AWS Region, this is where you bring them out. Insert them into the code above.
Next is the initialization of the AWSIoTDataManager. The data manager provides a mechanism for connecting, publishing, subscribing and modifying thing shadows, so it’s perfect for facilitating the connection between your iOS app and your fleet. Here’s the SDK documentation on the class.
To access your IoT Endpoint: in the AWS console go to IoT Core → Settings and you’ll find it at the top of the page. Be sure to prefix the string with wss://
and suffix it with /mqtt
.
In order to authenticate with AWS IoT, a client ID is required. This can be acquired via an AWSCredentialsProvider
object using the getIdentityId()
method.
Calling this method returns an AWSTask<NSString *>
object, which is the AWS SDK’s mechanism for handling asynchronous tasks. In my app, I wrote a function with a promise wrapper to return the client ID, but explaining that is beyond the scope of this article, so I’ll simply illustrate how to fetch the ID using a completion handler. You can modify the asynchronous return however you wish.
The following function assumes a successful acquisition of a client ID and illustrates how to connect to AWS IoT:
Debugging connection errors
This method is extremely information sparse in error conditions and hence debugging can be difficult. I haven’t had many issues myself, but if they occur for you, my recommendation would be to inspect the AWS object instances in the code and ensure they're not incorrectly initialized. Failing this, consider peripheral events to give you insight. Likely causes of connection failure are auth issues — incorrect or improperly created or attached policies or incorrect region/identity pool ID.
Once a successful connection is established, it becomes possible to publish and subscribe via the AWS IoT MQTT message broker (which is called the ‘Device Gateway’).
The above function registers subscriptions to an array of topics, handling reception via an inline function.
The AWSIoTDataManager methods to publish a message are very simple, and different options are offered between publishing a data/string payload and taking an ackCallback
argument — 4x (2²) permutations of these. A simple example of publishing a string is shown below.
The AWSIoTDataManager class is fairly well documented. You can explore the full feature set here.
Depending on your requirements, there are many more capabilities of the AWS iOS SDK in the realm of IoT. Many relate to platform and device management. You can explore all the IoT related functionality in the SDK documentation. If you do want to do more with your iOS app, remember to ensure your Cognito Identity Pool has an appropriate IoT policy attached to its roles.
Thanks for reading, I really hope you managed to connect your app without too many headaches. If you have any questions please drop them in the comments. I’m also always looking to improve, so any constructive criticism/feedback from experienced engineers/devs would be greatly appreciated!
This post was originally published by Josh Perry on Medium.
New Podcast Episode
Recent Articles