CocoaMQTT v2.0: the first iOS client supporting MQTT 5.0

In August 2017, OASIS MQTT Technical Committee officially released the for Public Review MQTT 5.0 Draft of. In 2018, MQTT 5.0 was officially released. However, until now, there is still no client SDK fully supporting MQTT 5.0 in Apple ecosystem.

CocoaMQTT It is the MQTT CLIENT SDK provided by EMQ team for iOS developers. At present, it is widely used by iOS developers.

In order to make up for the gap in MQTT 5.0 support in Apple ecology, the EMQ team recently officially released the new version of CocoaMQTT v2.0. CocoaMQTT v2.0 supports MQTT 5.0, is compatible with version 3.1.1, and supports iOS, tvOS and OSX operating systems. Users can now connect iOS system devices to MQTT 5.0 cloud services through CocoaMQTT, and enjoy the powerful function bonus brought by MQTT 5.0.

CocoaMQTT was developed in Swift language instead of Objective-C. This is because Swift is a type safe language with richer support for protocols. Protocol oriented programming can be realized in combination with extension, generics and association types, so as to greatly improve the flexibility of code.

In addition, at the WWDC 2021 conference, Apple announced a major update to the concurrency model in Swift language: the Actor concurrency model implemented by the compiler and the addition of Actor reference types to help developers avoid data competition.

Therefore, we believe that MQTT In related I/O-Intensive concurrent applications, Swift's performance will be more expected than Objective-C.

MQTT 5.0 vs MQTT 3.1.1

MQTT 3.1.1 still has many imperfections. For example, when the connection is abnormally disconnected, the reason cannot be notified to the opposite end. MQTT 5.0 has made many changes based on MQTT 3.1.1, but it is not downward compatible.

Version 5.0 of MQTT protocol adds session / message delay function, reason code, subject alias, in flight flow control, user attribute, shared subscription and other functions, as well as AUTH message to enhance authentication security. Among them, the reason code and user Property fields enable MQTT 5.0 to carry more context information, so as to solve the problem that it is difficult to deal with in version 3.1.1 due to incomplete protocol.

The main functional advantages of MQTT 5.0 are:

  • Further support larger scale scalable systems
  • More detailed error reporting and handling mechanisms
  • Standardized operation of common modes such as capacity exploration and request response
  • Extensible User Property
  • Improve performance and support small clients
  • Session hold and message timeout settings
  • New support for Req/Rsp message mode

Use of CocoaMQTT client

This article will use the information provided by EMQ Free public MQTT server Introduce the use of CocoaMQTT function. This service is based on MQTT cloud service EMQ X Cloud creation.

The server access information is as follows:

  • Broker: broker-cn.emqx.io
  • TCP Port: 1883
  • Websocket Port: 8083
  • TCP/TLS port: 8883
  • Websocket/TLS port: 8084

Connect to MQTT service

We can see that MQTT 5.0 has added many properties. The Property field allows users to complete the requirements in more detail according to their own situation.

///MQTT 5.0
let clientID = "CocoaMQTT-" + String(ProcessInfo().processIdentifier)
let mqtt5 = CocoaMQTT5(clientID: clientID, host: "broker-cn.emqx.io", port: 1883)

let connectProperties = MqttConnectProperties()
connectProperties.topicAliasMaximum = 0
connectProperties.sessionExpiryInterval = 0
connectProperties.receiveMaximum = 100
connectProperties.maximumPacketSize = 500
mqtt5.connectProperties = connectProperties

mqtt5.username = "test"
mqtt5.password = "public"
mqtt5.willMessage = CocoaMQTTWill(topic: "/will", message: "dieout")
mqtt5.keepAlive = 60
mqtt5.delegate = self
mqtt5.connect()

///MQTT 3.1.1
let clientID = "CocoaMQTT-" + String(ProcessInfo().processIdentifier)
let mqtt = CocoaMQTT(clientID: clientID, host: "broker-cn.emqx.io", port: 1883)
mqtt.username = "test"
mqtt.password = "public"
mqtt.willMessage = CocoaMQTTWill(topic: "/will", message: "dieout")
mqtt.keepAlive = 60
mqtt.delegate = self
mqtt.connect()

Subscribe to topics

MQTT 5.0 adds subscription options and other operations to MQTT 3.1.1.

///MQTT 5.0
mqtt5.subscribe("chat/room/animals/client/+", qos: CocoaMQTTQoS.qos1)
//or
//let subscriptions : [MqttSubscription] = [MqttSubscription(topic: "chat/room/animals/client/+"),MqttSubscription(topic: "chat/room/foods/client/+"),MqttSubscription(topic: "chat/room/trees/client/+")]
//mqtt.subscribe(subscriptions)

///MQTT 3.1.1
mqtt.subscribe("chat/room/animals/client/+", qos: CocoaMQTTQoS.qos1)
//or
//let subscriptions : [(String, CocoaMQTTQoS)] = [("chat/room/animals/client/+", qos: CocoaMQTTQoS.qos1),("chat/room/foods/client/+", qos: CocoaMQTTQoS.qos1),("chat/room/trees/client/+", qos: CocoaMQTTQoS.qos1)]
//mqtt.subscribe(subscriptions)

Release news

///MQTT 5.0
mqtt5!.publish("chat/room/animals/client/" + animal!, withString: message!, qos: .qos1, DUP: false, retained: false, properties: publishProperties)

///MQTT 3.1.1
mqtt!.publish("chat/room/animals/client/" + animal!, withString: message!, qos: .qos1)

Automatic reconnection

MQTT is a protocol based on TCP long connection. In the actual use scenario, the connection interruption caused by network failure or signal problem is a common problem. Many developers will hope that the SDK can provide a convenient automatic reconnection method.

///MQTT 5.0
mqtt5!.autoReconnect = true

///MQTT 3.1.1
mqtt!.autoReconnect = true

One way and two-way SSL connection

///MQTT 5.0
mqtt5!.enableSSL = true

///MQTT 3.1.1
mqtt!.enableSSL = true

let clientCertArray = getClientCertFromP12File(certName: "client-keycert", certPassword: "MySecretPassword")
var sslSettings: [String: NSObject] = [:]
sslSettings[kCFStreamSSLCertificates as String] = clientCertArray

///MQTT 5.0
mqtt5!.sslSettings = sslSettings

///MQTT 3.1.1
mqtt!.sslSettings = sslSettings

If necessary, the. p12 file can be generated at the terminal using the following statement

1openssl pkcs12 -export -clcerts -in client-cert.pem -inkey client-key.pem -out client.p12

Set retention and will messages

Compared with MQTT 3.1.1, MQTT 5.0 has more attribute settings for users.

///MQTT 5.0
let lastWillMessage = CocoaMQTTMessage(topic: "/chat/room/animals/client/Sheep", string: "dieout")
lastWillMessage.retained = true
lastWillMessage.qos = .qos1
mqtt5!.willMessage = lastWillMessage

///MQTT 3.1.1
mqtt!.willMessage = CocoaMQTTMessage(topic: "/will", string: "dieout")

AUTH message

MQTT simply through CONNECT may not provide enough information for Server authentication, so MQTT 5.0 adds this function. Used for enhanced authentication between client and Server.

  let authProperties = MqttAuthProperties()
        mqtt5!.auth(reasonCode: CocoaMQTTAUTHReasonCode.continueAuthentication, authProperties: authProperties)

iOS applications running in the background

It is recommended to use the "Background fetch" mode or the "Background processing" mode added in IOS 13.

If you use the API s related to beginBackgroundTaskWithName and endBackgroundTask, you can keep the APP running in the background for 30 seconds.

summary

So far, we have completed connecting to the public MQTT server using the CocoaMQTT client, and realized the connection, message publishing and subscription between the client and the MQTT server.

For the complete code of the project, see https://github.com/emqx/Cocoa....

EMQ is committed to helping users easily and conveniently use MQTT to carry out Internet of things business. A series of our client SDK s are under continuous development. Please pay attention.

Tags: iOS SDK IoT MQTT

Posted on Wed, 24 Nov 2021 09:57:52 -0500 by duall