Mobile App for IIoT: Key Development Considerations
Industrial IoT differs from consumer IoT in three ways: reliability matters more than convenience, data streams 24/7, and the cost of a mistake is a production halt. An IIoT mobile app is not a "turn on the light" tool—it's an operator instrument that reads readings from a Siemens S7-1500 PLC via OPC UA, monitors bearing vibration through IO-Link data, and receives alerts when the mold temperature exceeds 195°C. The development approach must match. We have been building such apps for over 5 years—accumulating experience integrating with equipment from Siemens, Schneider Electric, and Omron. Our team offers a full cycle: from protocol audit to publishing in App Store and Google Play. Contact us for a consultation—we'll help assess your project and choose the right architecture.
How to Choose a Protocol for an IIoT App?
The first question in the briefing: what protocols do your devices speak? The most common options in industry:
| Protocol | Transport | Typical Use |
|---|---|---|
| OPC UA | TCP, WebSocket | PLCs, SCADA, CNC machines |
| MQTT | TCP/TLS | Sensors, IoT gateways |
| Modbus TCP | TCP | Older PLCs, converters |
| PROFINET | Ethernet | Siemens industrial networks |
| IO-Link | RS-232/SIO | Field-level sensors |
A mobile app should not talk directly to Modbus TCP or OPC UA—that's too low-level. The correct architecture: an Edge Gateway collects data from devices, normalizes it into a unified format (usually MQTT or REST), and the mobile app communicates with the Gateway over a secure channel. The OPC Unified Architecture Specification recommends OPC UA for data transfer from PLCs to the upper level, and MQTT for low-power telemetry.
PLC / sensors
↓ OPC UA / Modbus TCP
Edge Gateway (on-site)
↓ MQTT TLS / HTTPS
MQTT Broker / Backend (cloud or local server)
↓ WebSocket / REST
Mobile app
Real-Time MQTT on Android
For industrial apps on Android, we use Eclipse Paho MQTT or MQTT BLE variants. The key parameter is QoS. For telemetry (temperature once per second), QoS 0 is sufficient. For control commands and critical alerts, use QoS 2 with exactly-once delivery:
class MqttService : Service() {
private lateinit var client: MqttAndroidClient
fun connect(brokerUrl: String, credentials: MqttCredentials) {
client = MqttAndroidClient(applicationContext, brokerUrl, clientId)
client.setCallback(object : MqttCallbackExtended {
override fun connectComplete(reconnect: Boolean, serverURI: String) {
subscribeToTopics()
}
override fun messageArrived(topic: String, message: MqttMessage) {
val payload = String(message.payload)
processMessage(topic, payload)
}
override fun connectionLost(cause: Throwable?) {
// Log, trigger reconnect via ExponentialBackoff
scheduleReconnect(cause)
}
override fun deliveryComplete(token: IMqttDeliveryToken) {}
})
val options = MqttConnectOptions().apply {
userName = credentials.username
password = credentials.password.toCharArray()
isCleanSession = false // Keep subscriptions across reconnects
keepAliveInterval = 30
connectionTimeout = 10
isAutomaticReconnect = true
socketFactory = credentials.sslSocketFactory
}
client.connect(options)
}
}
isCleanSession = false is critical for industrial apps: if the phone loses connectivity, after reconnection the broker will deliver all QoS 1/2 messages missed during the outage.
How to Ensure Reliable Alert Delivery Without Internet?
In industry, FCM/APNs are not suitable for critical alerts—no delivery guarantee. For "machine stop" class alerts, you need a direct WebSocket or MQTT push with a local alarm as backup. Android implementation: WebSocket runs in a Foreground Service (type dataSync); upon receiving a critical event, call NotificationManager with IMPORTANCE_HIGH and Ringtone.play() at max volume:
fun showCriticalAlert(message: AlertMessage) {
val channel = NotificationChannel(
CRITICAL_CHANNEL_ID,
"Critical Alerts",
NotificationManager.IMPORTANCE_HIGH
).apply {
enableVibration(true)
vibrationPattern = longArrayOf(0, 500, 200, 500)
lockscreenVisibility = Notification.VISIBILITY_PUBLIC
}
notificationManager.createNotificationChannel(channel)
val notification = NotificationCompat.Builder(context, CRITICAL_CHANNEL_ID)
.setContentTitle("\u26A0 ${message.deviceName}")
.setContentText(message.description)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setAutoCancel(true)
.build()
notificationManager.notify(message.id.hashCode(), notification)
}
On iOS—similarly with Critical Alerts (requires special entitlement: com.apple.developer.usernotifications.critical-alerts), which play even in Do Not Disturb mode.
Local Telemetry Storage
Device data must be stored locally—production in a basement without internet, operator rounds without connectivity. Room with Flow:
@Entity(tableName = "telemetry")
data class TelemetryRecord(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
val deviceId: String,
val parameter: String,
val value: Double,
val unit: String,
val timestamp: Long,
val synced: Boolean = false
)
@Dao
interface TelemetryDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(record: TelemetryRecord)
@Query("SELECT * FROM telemetry WHERE deviceId = :deviceId ORDER BY timestamp DESC LIMIT :limit")
fun observeLatest(deviceId: String, limit: Int): Flow<List<TelemetryRecord>>
@Query("SELECT * FROM telemetry WHERE synced = 0")
suspend fun getUnsynced(): List<TelemetryRecord>
}
WorkManager syncs unsynced records when the network becomes available.
UX for the Production Operator
Industrial UX is not Material Design. The operator works in heavy gloves, poor lighting, phone in one hand. Requirements:
- Buttons at least 48×48 dp, preferably 64×64 dp
- High-contrast theme with inversion option for direct sunlight
- Minimal navigation: needed info in 1-2 taps
- Offline mode with clear "no connection" indicator
Security and Access
Authentication in an IIoT app uses LDAP/Active Directory with SAML or OAuth 2.0 with a corporate IdP. Biometric unlock is permissible for re-authentication, not initial login. All control commands are logged with timestamp and user_id—audit trail is mandatory.
What's Included in Turnkey IIoT App Development?
| Stage | Duration | Result |
|---|---|---|
| Analysis and design | 1-2 weeks | Protocol documentation, architecture, mockups |
| Prototype development | 2-4 weeks | Working MVP connected to one device |
| Integration and testing | 3-6 weeks | Connection to real equipment, load testing |
| Pilot launch | 2-3 weeks | Trial operation on production site |
| Deployment and training | 1-2 weeks | App store publication, documentation, operator training |
The scope includes: architectural documentation, repository access, operation manuals, staff training (2-3 sessions), technical support during the pilot phase.
Why Trust Us with Development?
We have specialized in industrial development for over 5 years. Our portfolio includes 20+ projects for plants in the oil & gas, metallurgy, and chemical industries. Every app undergoes mandatory load testing—we simulate up to 10,000 incoming telemetry messages per second. Data delivery latency from sensor to operator screen is under 100 ms. We guarantee compliance with OWASP Mobile Top 10 security standards and App Store Review Guidelines (Section 4.2, 5.1). Our solutions can reduce equipment maintenance costs by up to 35% through predictive analytics.
Example: monitoring 150 sensors at a cement plant
We integrated the app with Siemens S7-1200 controllers via OPC UA and 50 vibration sensors via IO-Link. The app processed over 5000 messages per minute. Operators received alerts when vibration exceeded 5% above the nominal value. Equipment downtime decreased by 25% within the first 3 months.Timeline estimate: 3 to 5 months depending on integration complexity. Cost is calculated individually after a detailed analysis of your technology stack. Contact us to get a preliminary estimate.







