Front-End Web & Mobile

Bluetooth Low Energy (BLE) IoT Mobile Application with AWS Amplify, AWS IoT and Swift

This article was written by Ashu Joshi, Global Head, Enterprise Solutions, AWS Professional Services.


Bluetooth Low Energy (BLE) is a widely used protocol for building Internet of Things (IoT) products. Fitness products and wearables are good examples of BLE connected IoT products.

This post shows how to get started on your journey to build a connected platform for BLE devices. You will build an iOS app using AWS Amplify (Amplify), that reads data from an off the shelf BLE device and publishes to AWS IoT. You will use AWS Cloud Development Kit (CDK) to create AWS Amplify resources that will be used in the iOS app.

Solution overview

This solution uses Arduino Nano 33 BLE Sense (Nano) as an example of BLE Connected Product. The Nano will be programmed to send data over BLE to the iOS Application developed in Swift. The iOS application will publish the data using MQTT from the Nano to AWS IoT.

Arduino Nano connects to the IOS-Swift application over Bluetooth Low Energy. The IOS application uses Amplify to add support for Amazon Cognito and AWS IoT Core. Amazon Cognito User Pool is for authentication and Amazon Cognito Identity Pool for granting permissions to AWS resources. Amplify SDK is configured with resources created by AWS CDK.

Walkthrough

We will have to set up the AWS resources using CDK, configure Amplify to use the resources created by CDK, program the Arduino, and use Xcode for the iOS app.

  • Install the Arduino IDE and program the Nano BLE Sense device
  • Deploy the CDK stack and create resources in AWS
  • Setup the Xcode project, and provide resources to AWS Amplify

Code samples for this post and setup are found in the samples GitHub repository.

Prerequisites

For this walkthrough, you should have the following prerequisites:

To get started, clone the code repository on your local machine, and change to the source folder:

git clone https://github.com/aws-samples/aws-amplify-cdk-iot-ble-swift-app.git
cd aws-amplify-cdk-iot-ble-swift-app

Setting up AWS resources using AWS CDK

You will use CDK to setup the resources required for this project. A CDK stack has been provided in the blexstack folder. This CDK stack will setup resources required for configuring Amplify for the iOS app and additional resources to route data using AWS IoT Actions and Rules. Follow the steps below to deploy the stack (if this is the first time you are using CDK, you would need to run cdk bootstrap command prior to deploy):

cd blexstack
npm install
cdk deploy

The stack creates the following resources and logs the specifics to the terminal:

  • Project Region
  • Cognito Pool Id
  • Cognito Region
  • User Pool Id
  • User Pool Client ID
  • IoT Policy

The values for each of these resources will be used to configure Amplify support in the iOS app. The stack also creates an authenticated IAM role that grants permissions to the app user.

Amazon Cognito identities can be used to grant permissions to AWS IoT. The stack creates an IoT policy. The name of this policy has to be provided to the app. The iOS will attach the IoT policy to Cognito ID of the authenticated user.

Further information and detailed instructions on the CDK stack: aws-amplify-cdk-iot-ble-swift-app/blexstack/README.md

Programming the Arduino Nano 33 BLE Sense

  1. Install the Arduino IDE and board package for the Arduino Nano 33 BLE Sense. Following this, install all the libraries required for the sensors supported and the libraries for the sensors. See detailed instructions in the aws-amplify-cdk-iot-ble-swift-app/docs/ArduinoNano.md.
  2. Compile and upload the Arduino Sketch to the Nano connected to your computer using the micro-USB cable.
  3. The Serial Monitor in the Arduino IDE will show you the output of the program. After successful compile and upload, the sketch will start – waiting for a BLE connection with the iOS app. You can leave the Arduino Nano running and waiting for the connection. The iOS app will connect to the Nano.

Arduino IDE serial monitor showing output of Arduino Nano waiting to accept Bluetooth Low Energy connections

Further formation and detailed instructions on programming the Arduino Nano: aws-amplify-cdk-iot-ble-swift-app/docs/ArduinoNano.md

Deploying the iOS/Swift app on iPhone

You will learn how to use the resources created by CDK to configure Amplify support for the iOS application. The steps outlined below can be replicated with the source in the aws-amplify-cdk-iot-ble-swift-app/BLEX folder. You can also follow similar steps to integrate backend resources in your iOS Amplify project.

Steps

  1. Change to the iOS app directory (blex), install all the pods required by the project.
cd BLEX
pod install
  1. If you are starting the iOS project from scratch, create a podfile to include the following pods:
pod 'Amplify', '~> 1.0' #required Amplify dependency
pod 'Amplify/Tools', '~> 1.0' #allows to call Amplify CLI from within XCode
pod 'AmplifyPlugins/AWSCognitoAuthPlugin', '~> 1.0' #Cognito User Auth
pod 'AWSIoT' # Support for AWSIoT
pod 'AWSMobileClient'
  1. After installing all the required pods, the next step is to configure Amplify. Change into the BLEX subdirectory and copy emptyamplifyconfiguration.json to amplifyconfiguration.json.
cd BLEX
cp emptyamplifyconfiguration.json amplifyconfiguration.json
  1. To configure AWS IoT for the iOS app, get the end point for IoT for region and account used for project. AWS IoT configuration for this project is being stored in a file called Constants.swift.
aws iot describe-endpoint
  1. And open the project in Xcode – use the BLEX.xcworkspace file.
  2. Now edit the Constants.swift and amplifyconfiguration.json files to fill in with the values from the CDK deploy output in the previous section. The files would look something similar to below:
{
    "auth": {
            "plugins": {
                "awsCognitoAuthPlugin": {
                    "IdentityManager": {
                        "Default": {}
                    },
                    "CredentialsProvider": {
                        "CognitoIdentity": {
                            "Default": {
                                "PoolId": "us-east-2:498af5c5-56b9-40be-982b-dc48384001d7",
                                "Region": "us-east-2"
                            }
                        }
                    },
                    "CognitoUserPool": {
                        "Default": {
                            "PoolId": "us-east-2_QPy6g1Fo4",
                            "AppClientId": "5c5mfkabck6272shbi94khos4o",
                            "Region": "us-east-2"
                        }
                    },
                    "Auth": {
                        "Default": {
                            "authenticationFlowType": "USER_SRP_AUTH"
                        }
                    }
                }
            }
    }
}
// Specify the region, for example US East 2 it will AWSRegion.USEast2
let AWS_REGION = AWSRegionType.USEast2

// This is the endpoint in your AWS IoT console. eg:https://xxxxxxxxxx.iot.<region>.amazonaws.com
// Using the output of the 'aws iot describe-endpoint' provide the MQTT and IOT Endpoints below
let IOT_ENDPOINT = "https://a3mbjlk44aqsbg-ats.iot.us-east-2.amazonaws.com"
let MQTT_IOT_ENDPOINT = "wss://a3mbjlk44aqsbg-ats.iot.us-east-2.amazonaws.com"

// Fill the output from CDK Deploy for Cognito Pool ID
let IDENTITY_POOL_ID = "us-east-2:498af5c5-56b9-40be-982b-dc48384001d7"

// Fill the output for the IoT Policy Name below
let IOT_POLICY = "blexMobileAppIoTPermissionsPolicy"

// You can choose to keep the Publish and Subscribe topic used by the IOS app same as below
// Remember to change the IoT Rules and Actions if you change these to listen to the right topics
let IOT_PUBLISH_TOPIC = "blex"
let IOT_SUBSCRIBE_TOPIC = "blex/command"

//Used as keys to look up a reference of each manager
let AWS_IOT_DATA_MANAGER_KEY = "bleIoTData"
let AWS_IOT_MANAGER_KEY = "bleIoTManager"
  1. With the configuration for AWS IoT and Cognito in the project complete, you can now build the project either using the menu or the Cmd+B key combo. Building the project from the source would generate number of warnings that you can safely ignore for the prototype being built.
  2. Test the app by launching the iOS Simulator. Select the BLEX > iPhone Pro Max 12 and then click on the play icon on the left to start running the app in the iOS Simulator. The Simulator will prompt you with the login screen after successful launch:

When the IOS simulator finishes launching the application, it shows the login screen.

  1. Start with setting up a user. Click the Sign Up button on the Simulator using your mouse. On the sign-up screen, enter a Name, User Name, Password (CDK stack uses default policy – use a password with minimum 8 characters, requires numbers, special character, uppercase and lowercase letters) and a valid email address. When you click on Create Account – it will be followed with a prompt pop-up to enter the confirmationcode sent to your email. Check your email, and enter the code and click Ok. This will take you back to the Login screen, and now you can login to enter the app.

On the Create Account screen sign up using name, username, password and email address

Enter the confirmation code you received in your email in the pop up dialog box to confirm the sign up process.

Upon successful sign up, a pop up diaglog box will confirm success.

  1. You will need to use an iPhone to test the BLE data exchange. Connect your phone to your Mac and Xcode. Use Xcode to load and the run the application on your iPhone. Use the username and password created earlier to login. After successful login you are ready to test the data from Arduino Nano sent using BLE to the iOS/Swift application and from the app using MQTT to publish to AWS IoT Core.
  2. First you have to scan, and connect to the Arduino Nano. To do so, tap “Start Device Scan”, the app will detect all BLE devices in range and present a list. Select nanosense from this list. Selecting the Nano device will start the discovery of BLE services and characteristics supported. Upon finishing the discovery – the Start Data Capture will become ungrayed and touchable.
  3. Note: The iOS/Swift app after the first-time login of a user – also makes a call to attach the IoT Policy to the Cognito ID for the user. The IAM role assumed by the authenticated user has been granted permission to perform this operation. In production systems, the iOS/Swift application should use an authorized API Gateway and Lambda function to attach the Cognito ID to the Policy.
  4. To the see data being published to AWS IoT Core, log on to the AWS Console and select the region the stack was deployed in. Select the ‘IoT Core’ service and then down at the bottom of the menu on the left in the ‘Test’ section – click ‘MQTT Test Client’.
  5. Use the Subscribe section to subscribe to two topics:
    1. blex – this the topic that the iOS/Swift App is publishing the data to.
    2. An IoT Action & Rule has been setup to read from the blex topic and republish to data/${clientid()}. The rule publishes back to a topic with data/<CognitoID> associated with the user. Subscribe to another topic using this pattern – data/+

Use the MQTT Test Client in the AWS IoT Console to subscribe to the two topics – ‘blex’ topic used by the IOS app to publish sensor data from Arduino Nano

Use the MQTT Test Client in the AWS IoT Console to subscribe to the two topics – the ‘data/+’ topic to data modified by IoT Rule and republished back.

  1. You can also navigate to S3 service, and select the bucket created by the CDK stack to see the packets being stored in S3 by the second IoT Action & Rule.

Further formation and detailed instructions on IOS/Swift Application: aws-amplify-cdk-iot-ble-swift-app/docs/IOSSwiftApp.md

Cleaning up

To avoid incurring future charges, delete the resources. You can delete the resources by changing to the CDK directory and running the command:

cd blexstack
cdk destroy

Conclusion

In this blog post, I showed you how to build a BLE-connected solution on AWS, using AWS CDK to create backend resources and using them with to configure Amplify for the iOS App. The post demonstrated reading data from the BLE device, using Cognito ID to grant permissions to publish data to AWS IoT.

Further reading

Configuring Cognito User Pools to Communicate with AWS IoT Core

Amplify – use existing AWS resources

Author bio

Ashu Joshi

Ashu Joshi is Global Head, Enterprise Solutions in the AWS ProServe team. He helps our customers with Connected Products, IoT & AI/ML architecture and strategy. He has spent more than 10 years in the field of IoT and Machine Learning and has implemented solutions for dozens of Fortune 500 companies.