tencent cloud

iOS SDK
Last updated:2026-01-30 15:02:26
iOS SDK
Last updated: 2026-01-30 15:02:26

Feature Overview

CocoaMQTT is an MQTT client library written in Swift, designed specifically for iOS, macOS, and tvOS platforms.

CocoaMQTT supports MQTT 3.1.1 and MQTT 5.0 protocols, providing a complete MQTT feature implementation including connection, publish, subscribe, QoS, SSL/TLS, WebSocket, and other capabilities.

Cloud Resource Preparation

Please refer to create a resource operation steps to complete cloud resource preparation.

Preparing the Environment

System Requirements

iOS 10.0+ / macOS 10.12+ / tvOS 10.0+
Xcode 12.0+
Swift 5.0+

Install CocoaMQTT via CocoaPods

Add to your Podfile file:
target 'YourTarget' do
pod 'CocoaMQTT', '~> 2.1.6'
end
Then execute:
pod install
Note:
CocoaMQTT 2.x supports both MQTT 3.1.1 and MQTT 5.0 protocols, with different class names used for distinction (CocoaMQTT for 3.1.1 and CocoaMQTT5 for 5.0).

Install via Swift Package Manager

In Xcode:
1. Choose File > Swift Packages > Add Package Dependency
2. Enter repository URL: https://github.com/emqx/CocoaMQTT.git
3. Select version number or version range.
4. Import the module in your code: import CocoaMQTT

Install via Carthage

Add to the Cartfile file:
github "emqx/CocoaMQTT" "master"
Execute:
carthage update --platform iOS,macOS,tvOS --use-xcframeworks
Then drag the generated .xcframework into the project and set it to "Embed & Sign".

Example Code

Note:
This document is based on CocoaMQTT version 2.1.9. If you are using a different version, the APIs may differ.

Key APIs Overview for MQTT 5.0

When using MQTT 5.0 (CocoaMQTT5), please note the following key points:
1. Connection response callback parameters: didConnectAck receives 3 parameters.
mqtt.didConnectAck = { mqtt, ack, properties in
// ack is of CocoaMQTTCONNACKReasonCode type
// properties is of MqttDecodeConnAck? type
}
2. Connection success status: Use .success instead of .accept
if ack == .success { // Correct
// Connection successful
}
3. Subscription method: Use an array of MqttSubscription objects.
let subscriptions = [
MqttSubscription(topic: "home/test", qos: .qos1)
]
mqtt.subscribe(subscriptions)
4. Receive message callback: receives 4 parameters, payload is of [UInt8] type.
mqtt.didReceiveMessage = { mqtt, message, id, properties in
// message.payload is of [UInt8] type and needs to be converted
let content = String(data: Data(message.payload), encoding: .utf8) ?? ""
}
5. Publish message: requires passing the properties parameter.
mqtt.publish(topic, withString: message, qos: .qos1, properties: MqttPublishProperties())
6. Publish acknowledgement callback: receives 3 parameters.
mqtt.didPublishAck = { mqtt, id, properties in
print("Publish acknowledgement - ID: \\(id)")
}
7. Subscription result callback: receives 4 parameters.
mqtt.didSubscribeTopics = { mqtt, success, failed, properties in
// success is of type [(String, CocoaMQTTQoS)]
}
MQTT 5
MQTT 5 TLS
MQTT 3.1.1
MQTT 3.1.1 TLS

import CocoaMQTT

class MQTTManager {
var mqtt: CocoaMQTT5!
func setupMQTT() {
// Get the access point from the MQTT console:
// For users who implement VPC network integration via Private Link, use private network access point;
// For users accessing over the public network, ensure the public network security policy permits access, and the machine running the program has public network connectivity;
let host = "mqtt-xxx.mqtt.tencenttdmq.com"
let port: UInt16 = 1883
// A valid Client Identifier contains digits 0-9, lowercase English letters a-z, and uppercase English letters A-Z, with a total length of 1-23 characters
// See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901059
let clientID = "QuickStart"
mqtt = CocoaMQTT5(clientID: clientID, host: host, port: port)
// On the console --> Create account on the Authentication Tab, copy username and password
mqtt.username = "YOUR_USERNAME"
mqtt.password = "YOUR_PASSWORD"
mqtt.keepAlive = 60
mqtt.cleanSession = true
mqtt.autoReconnect = true
// Set the callback.
mqtt.didConnectAck = { mqtt, ack, _ in
print("Connection response: \\(ack)")
if ack == .success {
// MQTT topic
let pubTopic = "home/test"
// Subscribe to a topic.
let subscriptions = [
MqttSubscription(topic: pubTopic, qos: .qos1),
MqttSubscription(topic: "home/#", qos: .qos1),
MqttSubscription(topic: "home/+", qos: .qos1)
]
mqtt.subscribe(subscriptions)
print("Subscribed to the topic")
}
}
mqtt.didPublishMessage = { mqtt, message, id in
print("Message published successfully - ID: \\(id)")
}
mqtt.didPublishAck = { mqtt, id, _ in
print("Received publish acknowledgement - ID: \\(id)")
}
mqtt.didReceiveMessage = { mqtt, message, _, _ in
let content = String(data: Data(message.payload), encoding: .utf8) ?? ""
print("Received message - Topic: \\(message.topic), QoS: \\(message.qos.rawValue), Content: [\\(content)]")
}
mqtt.didSubscribeTopics = { mqtt, success, failed, _ in
print("Subscription successful: \\(success)")
if !failed.isEmpty {
print("Subscription failed: \\(failed)")
}
}
mqtt.didDisconnect = { mqtt, error in
if let error = error {
print("Disconnected: \\(error.localizedDescription)")
} else {
print("Disconnected")
}
}
// Connect to the server
_ = mqtt.connect()
}
func publishMessages() {
let pubTopic = "home/test"
let total = 16
for i in 0..<total {
let message = "Hello MQTT \\(i)"
print("Preparing to publish message \\(i)")
mqtt.publish(pubTopic, withString: message, qos: .qos1, properties: MqttPublishProperties())
print("Message published \\(i)")
// Delay 3 seconds
Thread.sleep(forTimeInterval: 3)
}
// Disconnect after waiting for 3 seconds
Thread.sleep(forTimeInterval: 3)
mqtt.disconnect()
}
}

import CocoaMQTT

class MQTTManagerTLS {
var mqtt: CocoaMQTT5!
func setupMQTT() {
// Get the access point from the MQTT console:
// For users who implement VPC network integration via Private Link, use private network access point;
// For users accessing over the public network, ensure the public network security policy permits access, and the machine running the program has public network connectivity;
let host = "mqtt-xxx.mqtt.tencenttdmq.com"
let port: UInt16 = 8883
// A valid Client Identifier contains digits 0-9, lowercase English letters a-z, and uppercase English letters A-Z, with a total length of 1-23 characters
// See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901059
let clientID = "QuickStartTls"
mqtt = CocoaMQTT5(clientID: clientID, host: host, port: port)
// On the console --> Create account on the Authentication Tab, copy username and password
mqtt.username = "YOUR_USERNAME"
mqtt.password = "YOUR_PASSWORD"
mqtt.keepAlive = 60
mqtt.cleanSession = true
mqtt.autoReconnect = true
// Enable SSL/TLS
mqtt.enableSSL = true
mqtt.allowUntrustCACertificate = false
// Set the callback.
mqtt.didConnectAck = { mqtt, ack, _ in
print("Connection response: \\(ack)")
if ack == .success {
// MQTT topic
let topicName = "home/test"
// Subscribe to a topic.
let subscriptions = [
MqttSubscription(topic: topicName, qos: .qos1),
MqttSubscription(topic: "home/#", qos: .qos1),
MqttSubscription(topic: "home/+", qos: .qos1)
]
mqtt.subscribe(subscriptions)
}
}
mqtt.didPublishMessage = { mqtt, message, id in
print("Message published successfully - ID: \\(id)")
}
mqtt.didPublishAck = { mqtt, id, _ in
print("Received publish acknowledgement - ID: \\(id)")
}
mqtt.didReceiveMessage = { mqtt, message, _, _ in
let content = String(data: Data(message.payload), encoding: .utf8) ?? ""
print("Received message - Topic: \\(message.topic), QoS: \\(message.qos.rawValue), Content: [\\(content)]")
}
mqtt.didSubscribeTopics = { mqtt, success, failed, _ in
for (topic, qos) in success {
print("Subscription successful - Topic: \\(topic), Granted-QoS: \\(qos)")
}
if !failed.isEmpty {
print("Subscription failed: \\(failed)")
}
}
mqtt.didDisconnect = { mqtt, error in
if let error = error {
print("Disconnected: \\(error.localizedDescription)")
} else {
print("Disconnected")
}
}
// Connect to the server
_ = mqtt.connect()
}
func publishMessages() {
let topicName = "home/test"
let total = 16
for i in 0..<total {
let message = "Hello MQTT \\(i)"
print("Preparing to publish message \\(i)")
mqtt.publish(topicName, withString: message, qos: .qos1, properties: MqttPublishProperties())
print("Message published \\(i)")
// Delay 3 seconds
Thread.sleep(forTimeInterval: 3)
}
// Disconnect after waiting for 3 seconds
Thread.sleep(forTimeInterval: 3)
mqtt.disconnect()
}
}



import CocoaMQTT

class MQTTManager311 {
var mqtt: CocoaMQTT!
func setupMQTT() {
// Get the access point from the MQTT console:
// For users who implement VPC network integration via Private Link, use private network access point;
// For users accessing over the public network, ensure the public network security policy permits access, and the machine running the program has public network connectivity;
let host = "mqtt-xxx.mqtt.tencenttdmq.com"
let port: UInt16 = 1883
// A valid Client Identifier contains digits 0-9, lowercase English letters a-z, and uppercase English letters A-Z, with a total length of 1-23 characters
// See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901059
let clientID = "QuickStart"
mqtt = CocoaMQTT(clientID: clientID, host: host, port: port)
// On the console --> Create account on the Authentication Tab, copy username and password
mqtt.username = "YOUR_USERNAME"
mqtt.password = "YOUR_PASSWORD"
mqtt.keepAlive = 60
mqtt.cleanSession = true
mqtt.autoReconnect = true
// Set proxy
mqtt.delegate = self
// Connect to the server
_ = mqtt.connect()
}
func publishMessages() {
// Confirm that the first-level topic "home" has been created in the MQTT console
let pubTopic = "home/test"
let total = 16
for i in 0..<total {
let message = "Hello MQTT \\(i)"
print("Preparing to publish message \\(i)")
mqtt.publish(pubTopic, withString: message, qos: .qos1)
print("Message published \\(i)")
// Delay 3 seconds
Thread.sleep(forTimeInterval: 3)
}
// Disconnect after waiting for 3 seconds
Thread.sleep(forTimeInterval: 3)
mqtt.disconnect()
}
}

// MARK: - CocoaMQTTDelegate
extension MQTTManager311: CocoaMQTTDelegate {
func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {
print("Connection response: \\(ack)")
if ack == .accept {
// Confirm that the first-level topic "home" has been created in the MQTT console
let pubTopic = "home/test"
let topicFilters = [pubTopic, "home/#", "home/+"]
// Subscribe to a topic.
mqtt.subscribe(topicFilters, qos: [.qos1, .qos1, .qos1])
print("Subscribed to \\(topicFilters.count) topics")
}
}
func mqtt(_ mqtt: CocoaMQTT, didPublishMessage message: CocoaMQTTMessage, id: UInt16) {
print("Message published successfully - ID: \\(id)")
}
func mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) {
print("Received publish acknowledgement - Packet-ID: \\(id)")
}
func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {
let content = message.string ?? ""
print("Received message - Topic: \\(message.topic), QoS: \\(message.qos.rawValue), Dup: \\(message.duplicated), Retained: \\(message.retained), Content: [\\(content)]")
}
func mqtt(_ mqtt: CocoaMQTT, didSubscribeTopics success: NSDictionary, failed: [String]) {
print("Subscription successful: \\(success)")
if !failed.isEmpty {
print("Subscription failed: \\(failed)")
}
}
func mqtt(_ mqtt: CocoaMQTT, didUnsubscribeTopics topics: [String]) {
print("Unsubscribe: \\(topics)")
}
func mqttDidPing(_ mqtt: CocoaMQTT) {
// Heartbeat
}
func mqttDidReceivePong(_ mqtt: CocoaMQTT) {
// Heartbeat response
}
func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: Error?) {
if let error = err {
print("Disconnected: \\(error.localizedDescription)")
} else {
print("Disconnected")
}
}
}

import CocoaMQTT

class MQTTManager311TLS {
var mqtt: CocoaMQTT!
func setupMQTT() {
// Get the access point from the MQTT console:
// For users who implement VPC network integration via Private Link, use private network access point;
// For users accessing over the public network, ensure the public network security policy permits access, and the machine running the program has public network connectivity;
let host = "mqtt-xxx.mqtt.tencenttdmq.com"
let port: UInt16 = 8883
// A valid Client Identifier contains digits 0-9, lowercase English letters a-z, and uppercase English letters A-Z, with a total length of 1-23 characters
// See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901059
let clientID = "ClientQuickStartTls"
mqtt = CocoaMQTT(clientID: clientID, host: host, port: port)
// On the console --> Create account on the Authentication Tab, copy username and password
mqtt.username = "YOUR_USERNAME"
mqtt.password = "YOUR_PASSWORD"
mqtt.keepAlive = 60
mqtt.cleanSession = true
mqtt.autoReconnect = true
// Enable SSL/TLS
mqtt.enableSSL = true
mqtt.allowUntrustCACertificate = false
// Set proxy
mqtt.delegate = self
// Connect to the server
_ = mqtt.connect()
}
func publishMessages() {
// Confirm that the first-level topic "home" has been created in the MQTT console
let topic = "home/test"
let total = 16
for i in 0..<total {
let message = "Hello MQTT \\(i)"
print("Preparing to publish message \\(i)")
mqtt.publish(topic, withString: message, qos: .qos1)
print("Message published \\(i)")
// Delay 1 second
Thread.sleep(forTimeInterval: 1)
}
// Disconnect after waiting for 3 seconds
Thread.sleep(forTimeInterval: 3)
mqtt.disconnect()
}
}

// MARK: - CocoaMQTTDelegate
extension MQTTManager311TLS: CocoaMQTTDelegate {
func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {
print("Connection response: \\(ack)")
if ack == .accept {
let topicFilters = ["home/test"]
// Subscribe to a topic.
mqtt.subscribe(topicFilters, qos: [.qos1])
print("Subscribed to \\(topicFilters.count) topics")
}
}
func mqtt(_ mqtt: CocoaMQTT, didPublishMessage message: CocoaMQTTMessage, id: UInt16) {
// Message publishing completed
}
func mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) {
print("Received publish acknowledgement - Packet-ID: \\(id)")
}
func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {
let content = message.string ?? ""
print("Received message - Topic: \\(message.topic), QoS: \\(message.qos.rawValue), Content: [\\(content)]")
}
func mqtt(_ mqtt: CocoaMQTT, didSubscribeTopics success: NSDictionary, failed: [String]) {
print("Subscription successful: \\(success)")
}
func mqtt(_ mqtt: CocoaMQTT, didUnsubscribeTopics topics: [String]) {
print("Unsubscribe: \\(topics)")
}
func mqttDidPing(_ mqtt: CocoaMQTT) {
// Heartbeat
}
func mqttDidReceivePong(_ mqtt: CocoaMQTT) {
// Heartbeat response
}
func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: Error?) {
if let error = err {
print("Disconnected: \\(error.localizedDescription)")
} else {
print("Disconnected")
}
}
}

Parameter Description

Parameter
Description
pubTopic
The target topic for the message to be published.
Message topics can contain multiple levels, separated by '/'. The first level Topic needs to be created on the console Topic Tab page. For details, refer to Topic Names and Topic Filters.
topicFilters
One or more subscription expressions.
Subscription expressions can contain wildcards (Wildcards), for details, refer to Topic Names and Topic Filters.
qos
QoS array, The array length must match the number of Topic Filters elements.
The most commonly used QoS is 1, which is At-Least-Once delivery. For details, refer to Quality of Service levels and protocol flows.
host
MQTT instance endpoint host address. In the console, under the target cluster Basic Information > Access Information module, copy it. The location is shown in the figure below.
Standard access point: mqtt-xxx.mqtt.tencenttdmq.com (port 1883)
TLS access point: mqtt-xxx.mqtt.tencenttdmq.com (port 8883)
Standard WebSocket access point: mqtt-xxx.mqtt.tencenttdmq.com (port 80, path /mqtt)
TLS WebSocket access point: mqtt-xxx.mqtt.tencenttdmq.com (port 443, path /mqtt)

clientID
Device unique identifier: such as vehicle identification number (VIN), product serial number, and so on.
A valid Client Identifier contains: digits 0-9, lowercase letters a-z, uppercase letters A-Z; with a total length of 1-23 characters. For details, refer to Client Identifier.
username
Connection username can be copied from the Authentication Management page under Cluster Details in the console.

password
The password matching the Connection Username can be copied from the Authentication Management page on the cluster details console.

Was this page helpful?
You can also Contact Sales or Submit a Ticket for help.
Yes
No

Feedback