功能概述
CocoaMQTT 是一个使用 Swift 编写的 MQTT 客户端库,专为 iOS、macOS 和 tvOS 平台设计。
CocoaMQTT 支持 MQTT 3.1.1 和 MQTT 5.0 协议,提供了完整的 MQTT 功能实现,包括连接、发布、订阅、QoS、SSL/TLS、WebSocket 等特性。
云资源准备
环境准备
系统要求
iOS 10.0+ / macOS 10.12+ / tvOS 10.0+
Xcode 12.0+
Swift 5.0+
通过 CocoaPods 安装 CocoaMQTT
在您的
Podfile 文件中添加:target 'YourTarget' dopod 'CocoaMQTT', '~> 2.1.6'end
然后执行:
pod install
说明:
CocoaMQTT 2.x 同时支持 MQTT 3.1.1 和 MQTT 5.0 协议,使用不同的类名区分 (
CocoaMQTT 用于 3.1.1,CocoaMQTT5 用于 5.0)。通过 Swift Package Manager 安装
在 Xcode 中:
1. 选择 File > Swift Packages > Add Package Dependency
2. 输入仓库地址:
https://github.com/emqx/CocoaMQTT.git3. 选择版本号或版本范围
4. 在代码中导入模块:
import CocoaMQTT通过 Carthage 安装
在
Cartfile 文件中添加:github "emqx/CocoaMQTT" "master"
执行:
carthage update --platform iOS,macOS,tvOS --use-xcframeworks
然后将生成的
.xcframework 拖入项目,并设置为 "Embed & Sign"。示例代码
注意:
本文档基于 CocoaMQTT 2.1.9 版本,如果您使用的是其他版本,API 可能有所不同。
MQTT 5.0 关键 API 说明
在使用 MQTT 5.0 (
CocoaMQTT5) 时,请注意以下关键点:1. 连接响应回调参数:
didConnectAck 接收 3 个参数mqtt.didConnectAck = { mqtt, ack, properties in// ack 是 CocoaMQTTCONNACKReasonCode 类型// properties 是 MqttDecodeConnAck? 类型}
2. 连接成功状态: 使用
.success 而不是 .acceptif ack == .success { // 正确// 连接成功}
3. 订阅方法: 使用
MqttSubscription 对象数组let subscriptions = [MqttSubscription(topic: "home/test", qos: .qos1)]mqtt.subscribe(subscriptions)
4. 接收消息回调: 接收 4 个参数,payload 是
[UInt8] 类型mqtt.didReceiveMessage = { mqtt, message, id, properties in// message.payload 是 [UInt8] 类型,需要转换let content = String(data: Data(message.payload), encoding: .utf8) ?? ""}
5. 发布消息: 需要传入
properties 参数mqtt.publish(topic, withString: message, qos: .qos1, properties: MqttPublishProperties())
6. 发布确认回调: 接收 3 个参数
mqtt.didPublishAck = { mqtt, id, properties inprint("消息发布确认 - ID: \\(id)")}
7. 订阅结果回调: 接收 4 个参数
mqtt.didSubscribeTopics = { mqtt, success, failed, properties in// success 是 [(String, CocoaMQTTQoS)] 类型}
import CocoaMQTTclass MQTTManager {var mqtt: CocoaMQTT5!func setupMQTT() {// 从MQTT控制台获取接入点:// 通过Private Link实现VPC网络打通的用户, 使用内网接入点;// 通过公网访问的用户, 确保公网安全策略允许, 程序运行机器有公网接入;let host = "mqtt-xxx.mqtt.tencenttdmq.com"let port: UInt16 = 1883// 合法的Client Identifier包含 数字0-9, 小写英文字母a-z, 以及大写英文字母A-Z, 总长度为1-23个字符// 参考 https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901059let clientID = "QuickStart"mqtt = CocoaMQTT5(clientID: clientID, host: host, port: port)// 在控制台 --> 认证 Tab页创建账户, 复制用户名和密码mqtt.username = "YOUR_USERNAME"mqtt.password = "YOUR_PASSWORD"mqtt.keepAlive = 60mqtt.cleanSession = truemqtt.autoReconnect = true// 设置回调mqtt.didConnectAck = { mqtt, ack, _ inprint("连接响应: \\(ack)")if ack == .success {// MQTT topiclet pubTopic = "home/test"// 订阅主题let subscriptions = [MqttSubscription(topic: pubTopic, qos: .qos1),MqttSubscription(topic: "home/#", qos: .qos1),MqttSubscription(topic: "home/+", qos: .qos1)]mqtt.subscribe(subscriptions)print("已订阅主题")}}mqtt.didPublishMessage = { mqtt, message, id inprint("消息发布成功 - ID: \\(id)")}mqtt.didPublishAck = { mqtt, id, _ inprint("收到发布确认 - ID: \\(id)")}mqtt.didReceiveMessage = { mqtt, message, _, _ inlet content = String(data: Data(message.payload), encoding: .utf8) ?? ""print("收到消息 - Topic: \\(message.topic), QoS: \\(message.qos.rawValue), 内容: [\\(content)]")}mqtt.didSubscribeTopics = { mqtt, success, failed, _ inprint("订阅成功: \\(success)")if !failed.isEmpty {print("订阅失败: \\(failed)")}}mqtt.didDisconnect = { mqtt, error inif let error = error {print("连接断开: \\(error.localizedDescription)")} else {print("连接断开")}}// 连接到服务器_ = mqtt.connect()}func publishMessages() {let pubTopic = "home/test"let total = 16for i in 0..<total {let message = "Hello MQTT \\(i)"print("准备发布消息 \\(i)")mqtt.publish(pubTopic, withString: message, qos: .qos1, properties: MqttPublishProperties())print("已发布消息 \\(i)")// 延迟3秒Thread.sleep(forTimeInterval: 3)}// 等待3秒后断开连接Thread.sleep(forTimeInterval: 3)mqtt.disconnect()}}
import CocoaMQTTclass MQTTManagerTLS {var mqtt: CocoaMQTT5!func setupMQTT() {// 从MQTT控制台获取接入点:// 通过Private Link实现VPC网络打通的用户, 使用内网接入点;// 通过公网访问的用户, 确保公网安全策略允许, 程序运行机器有公网接入;let host = "mqtt-xxx.mqtt.tencenttdmq.com"let port: UInt16 = 8883// 合法的Client Identifier包含 数字0-9, 小写英文字母a-z, 以及大写英文字母A-Z, 总长度为1-23个字符// 参考 https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901059let clientID = "QuickStartTls"mqtt = CocoaMQTT5(clientID: clientID, host: host, port: port)// 在控制台 --> 认证 Tab页创建账户, 复制用户名和密码mqtt.username = "YOUR_USERNAME"mqtt.password = "YOUR_PASSWORD"mqtt.keepAlive = 60mqtt.cleanSession = truemqtt.autoReconnect = true// 启用 SSL/TLSmqtt.enableSSL = truemqtt.allowUntrustCACertificate = false// 设置回调mqtt.didConnectAck = { mqtt, ack, _ inprint("连接响应: \\(ack)")if ack == .success {// MQTT topiclet topicName = "home/test"// 订阅主题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 inprint("消息发布成功 - ID: \\(id)")}mqtt.didPublishAck = { mqtt, id, _ inprint("收到发布确认 - ID: \\(id)")}mqtt.didReceiveMessage = { mqtt, message, _, _ inlet content = String(data: Data(message.payload), encoding: .utf8) ?? ""print("收到消息 - Topic: \\(message.topic), QoS: \\(message.qos.rawValue), 内容: [\\(content)]")}mqtt.didSubscribeTopics = { mqtt, success, failed, _ infor (topic, qos) in success {print("订阅成功 - Topic: \\(topic), Granted-QoS: \\(qos)")}if !failed.isEmpty {print("订阅失败: \\(failed)")}}mqtt.didDisconnect = { mqtt, error inif let error = error {print("连接断开: \\(error.localizedDescription)")} else {print("连接断开")}}// 连接到服务器_ = mqtt.connect()}func publishMessages() {let topicName = "home/test"let total = 16for i in 0..<total {let message = "Hello MQTT \\(i)"print("准备发布消息 \\(i)")mqtt.publish(topicName, withString: message, qos: .qos1, properties: MqttPublishProperties())print("已发布消息 \\(i)")// 延迟3秒Thread.sleep(forTimeInterval: 3)}// 等待3秒后断开连接Thread.sleep(forTimeInterval: 3)mqtt.disconnect()}}
import CocoaMQTTclass MQTTManager311 {var mqtt: CocoaMQTT!func setupMQTT() {// 从MQTT控制台获取接入点:// 通过Private Link实现VPC网络打通的用户, 使用内网接入点;// 通过公网访问的用户, 确保公网安全策略允许, 程序运行机器有公网接入;let host = "mqtt-xxx.mqtt.tencenttdmq.com"let port: UInt16 = 1883// 合法的Client Identifier包含 数字0-9, 小写英文字母a-z, 以及大写英文字母A-Z, 总长度为1-23个字符// 参考 https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901059let clientID = "QuickStart"mqtt = CocoaMQTT(clientID: clientID, host: host, port: port)// 在控制台 --> 认证 Tab页创建账户, 复制用户名和密码mqtt.username = "YOUR_USERNAME"mqtt.password = "YOUR_PASSWORD"mqtt.keepAlive = 60mqtt.cleanSession = truemqtt.autoReconnect = true// 设置代理mqtt.delegate = self// 连接到服务器_ = mqtt.connect()}func publishMessages() {// 确认一级主题 "home" 在MQTT控制台已经创建let pubTopic = "home/test"let total = 16for i in 0..<total {let message = "Hello MQTT \\(i)"print("准备发布消息 \\(i)")mqtt.publish(pubTopic, withString: message, qos: .qos1)print("已发布消息 \\(i)")// 延迟3秒Thread.sleep(forTimeInterval: 3)}// 等待3秒后断开连接Thread.sleep(forTimeInterval: 3)mqtt.disconnect()}}// MARK: - CocoaMQTTDelegateextension MQTTManager311: CocoaMQTTDelegate {func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {print("连接响应: \\(ack)")if ack == .accept {// 确认一级主题 "home" 在MQTT控制台已经创建let pubTopic = "home/test"let topicFilters = [pubTopic, "home/#", "home/+"]// 订阅主题mqtt.subscribe(topicFilters, qos: [.qos1, .qos1, .qos1])print("已订阅 \\(topicFilters.count) 个主题")}}func mqtt(_ mqtt: CocoaMQTT, didPublishMessage message: CocoaMQTTMessage, id: UInt16) {print("消息发布成功 - ID: \\(id)")}func mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) {print("收到发布确认 - Packet-ID: \\(id)")}func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {let content = message.string ?? ""print("收到消息 - Topic: \\(message.topic), QoS: \\(message.qos.rawValue), Dup: \\(message.duplicated), Retained: \\(message.retained), 内容: [\\(content)]")}func mqtt(_ mqtt: CocoaMQTT, didSubscribeTopics success: NSDictionary, failed: [String]) {print("订阅成功: \\(success)")if !failed.isEmpty {print("订阅失败: \\(failed)")}}func mqtt(_ mqtt: CocoaMQTT, didUnsubscribeTopics topics: [String]) {print("取消订阅: \\(topics)")}func mqttDidPing(_ mqtt: CocoaMQTT) {// 心跳}func mqttDidReceivePong(_ mqtt: CocoaMQTT) {// 心跳响应}func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: Error?) {if let error = err {print("连接断开: \\(error.localizedDescription)")} else {print("连接断开")}}}
import CocoaMQTTclass MQTTManager311TLS {var mqtt: CocoaMQTT!func setupMQTT() {// 从MQTT控制台获取接入点:// 通过Private Link实现VPC网络打通的用户, 使用内网接入点;// 通过公网访问的用户, 确保公网安全策略允许, 程序运行机器有公网接入;let host = "mqtt-xxx.mqtt.tencenttdmq.com"let port: UInt16 = 8883// 合法的Client Identifier包含 数字0-9, 小写英文字母a-z, 以及大写英文字母A-Z, 总长度为1-23个字符// 参考 https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901059let clientID = "ClientQuickStartTls"mqtt = CocoaMQTT(clientID: clientID, host: host, port: port)// 在控制台 --> 认证 Tab页创建账户, 复制用户名和密码mqtt.username = "YOUR_USERNAME"mqtt.password = "YOUR_PASSWORD"mqtt.keepAlive = 60mqtt.cleanSession = truemqtt.autoReconnect = true// 启用 SSL/TLSmqtt.enableSSL = truemqtt.allowUntrustCACertificate = false// 设置代理mqtt.delegate = self// 连接到服务器_ = mqtt.connect()}func publishMessages() {// 确认一级主题 "home" 在MQTT控制台已经创建let topic = "home/test"let total = 16for i in 0..<total {let message = "Hello MQTT \\(i)"print("准备发布消息 \\(i)")mqtt.publish(topic, withString: message, qos: .qos1)print("已发布消息 \\(i)")// 延迟1秒Thread.sleep(forTimeInterval: 1)}// 等待3秒后断开连接Thread.sleep(forTimeInterval: 3)mqtt.disconnect()}}// MARK: - CocoaMQTTDelegateextension MQTTManager311TLS: CocoaMQTTDelegate {func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {print("连接响应: \\(ack)")if ack == .accept {let topicFilters = ["home/test"]// 订阅主题mqtt.subscribe(topicFilters, qos: [.qos1])print("已订阅 \\(topicFilters.count) 个主题")}}func mqtt(_ mqtt: CocoaMQTT, didPublishMessage message: CocoaMQTTMessage, id: UInt16) {// 消息发布完成}func mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) {print("收到发布确认 - Packet-ID: \\(id)")}func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {let content = message.string ?? ""print("收到消息 - Topic: \\(message.topic), QoS: \\(message.qos.rawValue), 内容: [\\(content)]")}func mqtt(_ mqtt: CocoaMQTT, didSubscribeTopics success: NSDictionary, failed: [String]) {print("订阅成功: \\(success)")}func mqtt(_ mqtt: CocoaMQTT, didUnsubscribeTopics topics: [String]) {print("取消订阅: \\(topics)")}func mqttDidPing(_ mqtt: CocoaMQTT) {// 心跳}func mqttDidReceivePong(_ mqtt: CocoaMQTT) {// 心跳响应}func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: Error?) {if let error = err {print("连接断开: \\(error.localizedDescription)")} else {print("连接断开")}}}
参数说明
参数 | 说明 |
pubTopic | 待发布消息的目标主题。 |
topicFilters | 一个或者多个订阅表达式。 |
qos | 服务质量数组,数组长度必须与 Topic Filters 数据保持一致。 |
host | MQTT 实例接入点主机地址,在控制台目标集群基本信息 > 接入信息模块复制。位置如下图所示。 标准接入点: mqtt-xxx.mqtt.tencenttdmq.com (端口 1883)TLS 接入点: mqtt-xxx.mqtt.tencenttdmq.com (端口 8883)标准 WebSocket 接入点: mqtt-xxx.mqtt.tencenttdmq.com (端口 80, 路径 /mqtt)TLS WebSocket 接入点: mqtt-xxx.mqtt.tencenttdmq.com (端口 443, 路径 /mqtt) ![]() |
clientID | 设备唯一标识符: 例如车辆车架号 VIN、产品序列号等。 |
username | 连接用户名,在控制台集群详情页认证管理页面复制。 ![]() |
password | 连接用户名匹配的密码,在控制台集群详情页认证管理页面复制。 |

