IoT Device Integration Through Mobile Applications
IoT integration is not one protocol, but a choice among several depending on physical distance, latency requirements, and energy consumption. An app for controlling a smart bulb in the next room and an app for monitoring industrial sensors on a production floor use different stacks, but face identical problems: connection breaks, state synchronization, and firmware updates.
Transport Selection
| Protocol | Range | Energy | Typical Use |
|---|---|---|---|
| BLE 5.0 | up to 100m | very low | wearables, sensors, locks |
| Wi-Fi | up to 50m indoors | medium | smart outlets, cameras |
| Zigbee / Z-Wave | up to 30m (mesh) | low | smart home |
| MQTT over TCP | via network | depends on network | industrial sensors |
| Matter | up to 50m | low | smart home (new standard) |
| Thread | mesh | low | Matter devices |
Mobile app most often acts as MQTT client or BLE Central. Direct Zigbee control from phone without hub is rare.
MQTT: The Most Common IoT Transport
MQTT is a pub/sub protocol over TCP. Broker (Mosquitto, AWS IoT, HiveMQ) receives messages and distributes to subscribers. Mobile app subscribes to device topics and publishes commands.
iOS—MQTT-Client-Framework or CocoaMQTT:
import CocoaMQTT
let client = CocoaMQTT(clientID: "mobile-\(UUID().uuidString)", host: "broker.example.com", port: 8883)
client.username = "user"
client.password = "pass"
client.enableSSL = true
client.keepAlive = 60
client.delegate = self
client.connect()
// Subscribe after connect:
func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {
guard ack == .accept else { return }
mqtt.subscribe("devices/sensor-01/temperature", qos: .qos1)
}
// Receive data:
func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {
if let payload = message.string {
let temp = Double(payload)
updateUI(temperature: temp)
}
}
// Publish command:
client.publish("devices/lamp-01/command", withString: "{\"state\":\"on\",\"brightness\":80}")
Android—Paho MQTT Android Service or HiveMQ MQTT Client:
// HiveMQ (more modern, no deprecated API)
val client = MqttClient.builder()
.useMqttVersion5()
.serverHost("broker.example.com")
.serverPort(8883)
.sslWithDefaultConfig()
.simpleAuth()
.username("user")
.password("pass".toByteArray())
.applySimpleAuth()
.buildAsync()
client.connect().whenComplete { _, throwable ->
if (throwable == null) {
client.subscribeWith()
.topicFilter("devices/sensor-01/temperature")
.qos(MqttQos.AT_LEAST_ONCE)
.callback { publish ->
val payload = String(publish.payloadAsBytes)
// update UI via Handler or LiveData
}
.send()
}
}
QoS and Its Impact on Reliability
-
QoS 0— at most once. Fast, no confirmation. For frequent updates (temperature every second)—normal. -
QoS 1— at least once. With confirmation, possible duplicates. For commands (on/off)—minimum. -
QoS 2— exactly once. Delivery guarantee without duplicates. For payments, critical commands.
Last Will Message
MQTT allows setting a message the broker sends when a client unexpectedly disconnects. For IoT this is important: if phone goes offline, other clients should know:
client.willMessage = CocoaMQTTMessage(
topic: "clients/mobile-app/status",
string: "{\"online\":false}"
)
Device State Synchronization
Main architectural problem: the app opened—what's the current state of all devices? MQTT doesn't store history by default. Solutions:
Retained messages. Device publishes its state with retain = true flag. Broker stores the last message and immediately returns on subscription. Mobile app on startup subscribes to devices/+/state and gets current states.
Shadow/Digital Twin. AWS IoT Device Shadow, Azure Device Twin—REST API for reading the last known device state. Suits when states are many and retained MQTT is insufficient.
OTA Firmware Updates
If device supports update via mobile app (BLE OTA or MQTT), this is separate work. Standards: Nordic DFU (for nRF chips via BLE), ESP-IDF OTA via HTTP/MQTT, MCU Bootloader via UART-bridge.
Nordic DFU on iOS—iOSDFULibrary, on Android—Android-DFU-Library. Both official libraries from Nordic Semiconductor.
Background Work and Notifications
Mobile app can't keep MQTT connection open constantly in background. For device event notifications—APNS/FCM: broker or backend sends push on state change.
On Android WorkManager + ForegroundService allow keeping MQTT connection if needed. On iOS—Background App Refresh with time-limit restrictions.
Integration timeline: from 1 week (MQTT client with basic control) to 3-4 weeks (full stack with OTA, state synchronization, push notifications). Cost is calculated individually.







