Controlling Your Phone From the Cloud

Gal Zahavi
The Startup
Published in
6 min readJul 28, 2020
Photo by Morning Brew on Unsplash

As someone who’s interested in computers and coding you keep hearing about the Internet of Things (IoT) and how cool it is. But, what use cases are there for our day to day lives other than colorful light bulbs or fridges that update you that you finished your ice cream last night after your Netflix binge? How can you enable the really interesting use cases of IoT? This article will show you, using Google Cloud IoT Core, how you can connect and control your phone from the cloud and open up new possibilities for your IoT ideas.

Objectives

  • Install Podfile and dependencies
  • Connect iPhone to IoT Core
  • Receive Commands from IoT Core to the iPhone

Before you begin

This tutorial assumes that you already have some background in iOS development and the basics of creating a registry, registering devices, and subscribing to a PubSub topic.

If you haven’t done this before, first go through the steps in IoT Core Getting Started to learn the basics of IoT Core.

Setting up and installing Pods

Before connecting to IoT Core using MQTT, you need to first install CocoaPods. CocoaPods is an application-level dependency manager for Swift and many other languages that provides a standard format for managing external libraries. If you are using OSX, you should already have CocoaPods installed. To manually download or update CocoaPods use:

sudo gem install cocoapods

After verifying that CocoaPods is installed, install the dependencies. For this step, you need to initialize CocoaPods. Using Terminal or similar program, run the following command from the directory that contains the .xcodeproj file:

pod init

This initializes the CocoaPods and creates a podfile where you can include the libraries you need.

After CocoaPods is successfully initialized, a podfile will be created. This podfile holds all of the dependencies needed for your project, let’s add SwiftJWT and CocoaMQTT to the podfile:

target ‘iOS_MQTT’ do
pod ‘SwiftJWT’
use_frameworks! # Add this if you are targeting iOS 8+
pod ‘CocoaMQTT’
end

Next, install the libraries to your project:

pod install

After the pods are successfully installed, make sure that the SwiftJWT and CocoaMQTT are included in the Xcode project. Click the .xcworkspace file to open the project.

If you’re getting an error that says “SwiftJWT or CocoaMQTT is not included” you will need to add them to the project dependencies.

To add these libraries :

  1. Open the File > Swift Packages > Add Package Dependency menu
  2. Select the project name
  3. For SwiftJWT paste git@github.com:IBM-Swift/Swift-JWT.git, or for CocoaMQTT paste git@github.com:emqx/CocoaMQTT.git

Generating the JSON Web Token (JWT)

Now that the library dependencies are installed, you can start creating the JWT.

For the iPhone to be able to connect, you need to provide a JWT for the password which IoT Core uses.

The following code creates a JWT with an issued at (iat), expiration (exp), and audience (aud) fields:

If these values are not correct, the client will reject the connection.

Note: The audience (aud field) should be set to the project ID from the Google Cloud Console

After the JWT is created, it will need to be signed using the private key. Copy the private_key.pem file and pass it in the privateKeyPair variable making sure that the variable includes BEGIN EC PRIVATE KEY and END EC PRIVATE KEY.

Use the claim that was created above and sign it using the privateKeyPair that corresponds to the device’s public key:

Now that the JWT is created, print it to see that all the information is correct. Go to JWT.io to check that all the information that was supplied matches.

Connecting iPhone to IoT Core

After the JWT is created, the cloudConnect function gets executed using the JWT; the cloudConnect function will create a CocoaMQTT client with the clientID, host, and port. You will need to provide the clientID which is the path of the device:

Set up the MQTT client by supplying the JWT that was created earlier as the password, note that the username is an empty string because IoT Core does not need to specify the username to connect:

The keepAlive parameter makes sure that the connection between the device and IoT Core stays connected by sending a heartbeat operation to the MQTT server. After the MQTT client is set up, it will try to connect to IoT Core.

Receiving Commands

After the mqtt.connect function has finished, the device should be connected. It may appear that the device is not connected because you don’t see any incoming messages, but this is expected because the MQTT client isn’t yet subscribed to the device’s command and configuration topics.

To subscribe to the command topic:

To subscribe to the configuration topic:

Note that for the command topic, you must include the wildcard(#) to match all subtopics. By subscribing to the wildcard topic, the device will receive commands sent to devices/{device-id}/commands, as well as commands sent to subtopics.

A callback function must be added to the connect function to print out the commands that are sent from IoT Core:

If you want to check for a specific message from IoT Core, you can add code that’s similar to the code below. The code below toggle’s the LED flash of the iPhone for commands with string payloads “on” or “off”.

Publishing Telemetry Data

After connecting and subscribing to the device’s configuration and command topics, you can finally publish shared state (state) and telemetry event (event) data.

Sending data is a matter of publishing to the topic for this device. To send data to the state topic, publish to /devices/{device-id}/state, and to send data to the event topic, publish to /devices/{device-id}/events.

The device’s event topic is for frequent updates from the device that are handled by Cloud infrastructure. The device’s state topic is for less frequent updates that indicate a shared and persistent state between Google Cloud and the device.

To publish to the state topic:

To publish to the event topic:

You can simply change the publish code to send sensor data as you will see in the next article.

Running the Sample

To run the sample all you need to do is to clone the repo from GitHub by running the following command:

git clone git@github.com:GoogleCloudPlatoform/google-cloud-iot-arduino.git

Then in your terminal go to google-cloud-iot arduino/examples/complex/esp32/ios-gateway/extras and run:

pod install

This will install your dependencies if you’re getting an error that says “SwiftJWT or CocoaMQTT is not included” you will need to add them to the project dependencies.

You can see how to do this in the Before You Begin section.

After the cocoapods are set up, you can run the project on your laptop or build it on your device.

After the application is running on your device you should be able to send “on” or “off” commands to toggle the flash, the application will not send event data because it’s expecting an ESP32 to connect.

If you want to send event data without connecting an ESP32 add the commands in the Publish Telemetry Data section into the publish function in the IoTBLEClient.swift file.

Next Steps

Now, this is a simple demonstration to show you how to connect your phone to IoT Core. IoT Core has access to all Google Cloud Services so from this point you can use any service, for example instead of uploading a message you can send an image to Cloud Vision API.

Follow my blog so you don’t miss part 2 of this article that will show you how to use this application to create an iPhone gateway that retrieves environmental data from an ESP32 using BLE.

--

--

Gal Zahavi
The Startup

The best thing about a boolean is even if you are wrong, you are only off by a bit.