iOS SDK

最近更新时间:2025-11-27 16:21:22

我的收藏

功能概述

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' do
pod '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.git
3. 选择版本号或版本范围
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 而不是 .accept
if 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 in
print("消息发布确认 - ID: \\(id)")
}
7. 订阅结果回调: 接收 4 个参数
mqtt.didSubscribeTopics = { mqtt, success, failed, properties in
// success 是 [(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() {
// 从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#_Toc3901059
let clientID = "QuickStart"
mqtt = CocoaMQTT5(clientID: clientID, host: host, port: port)
// 在控制台 --> 认证 Tab页创建账户, 复制用户名和密码
mqtt.username = "YOUR_USERNAME"
mqtt.password = "YOUR_PASSWORD"
mqtt.keepAlive = 60
mqtt.cleanSession = true
mqtt.autoReconnect = true
// 设置回调
mqtt.didConnectAck = { mqtt, ack, _ in
print("连接响应: \\(ack)")
if ack == .success {
// MQTT topic
let 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 in
print("消息发布成功 - ID: \\(id)")
}
mqtt.didPublishAck = { mqtt, id, _ in
print("收到发布确认 - ID: \\(id)")
}
mqtt.didReceiveMessage = { mqtt, message, _, _ in
let content = String(data: Data(message.payload), encoding: .utf8) ?? ""
print("收到消息 - Topic: \\(message.topic), QoS: \\(message.qos.rawValue), 内容: [\\(content)]")
}
mqtt.didSubscribeTopics = { mqtt, success, failed, _ in
print("订阅成功: \\(success)")
if !failed.isEmpty {
print("订阅失败: \\(failed)")
}
}
mqtt.didDisconnect = { mqtt, error in
if let error = error {
print("连接断开: \\(error.localizedDescription)")
} else {
print("连接断开")
}
}
// 连接到服务器
_ = mqtt.connect()
}
func publishMessages() {
let pubTopic = "home/test"
let total = 16
for 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 CocoaMQTT

class 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#_Toc3901059
let clientID = "QuickStartTls"
mqtt = CocoaMQTT5(clientID: clientID, host: host, port: port)
// 在控制台 --> 认证 Tab页创建账户, 复制用户名和密码
mqtt.username = "YOUR_USERNAME"
mqtt.password = "YOUR_PASSWORD"
mqtt.keepAlive = 60
mqtt.cleanSession = true
mqtt.autoReconnect = true
// 启用 SSL/TLS
mqtt.enableSSL = true
mqtt.allowUntrustCACertificate = false
// 设置回调
mqtt.didConnectAck = { mqtt, ack, _ in
print("连接响应: \\(ack)")
if ack == .success {
// MQTT topic
let 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 in
print("消息发布成功 - ID: \\(id)")
}
mqtt.didPublishAck = { mqtt, id, _ in
print("收到发布确认 - ID: \\(id)")
}
mqtt.didReceiveMessage = { mqtt, message, _, _ in
let content = String(data: Data(message.payload), encoding: .utf8) ?? ""
print("收到消息 - Topic: \\(message.topic), QoS: \\(message.qos.rawValue), 内容: [\\(content)]")
}
mqtt.didSubscribeTopics = { mqtt, success, failed, _ in
for (topic, qos) in success {
print("订阅成功 - Topic: \\(topic), Granted-QoS: \\(qos)")
}
if !failed.isEmpty {
print("订阅失败: \\(failed)")
}
}
mqtt.didDisconnect = { mqtt, error in
if let error = error {
print("连接断开: \\(error.localizedDescription)")
} else {
print("连接断开")
}
}
// 连接到服务器
_ = mqtt.connect()
}
func publishMessages() {
let topicName = "home/test"
let total = 16
for 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 CocoaMQTT

class 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#_Toc3901059
let clientID = "QuickStart"
mqtt = CocoaMQTT(clientID: clientID, host: host, port: port)
// 在控制台 --> 认证 Tab页创建账户, 复制用户名和密码
mqtt.username = "YOUR_USERNAME"
mqtt.password = "YOUR_PASSWORD"
mqtt.keepAlive = 60
mqtt.cleanSession = true
mqtt.autoReconnect = true
// 设置代理
mqtt.delegate = self
// 连接到服务器
_ = mqtt.connect()
}
func publishMessages() {
// 确认一级主题 "home" 在MQTT控制台已经创建
let pubTopic = "home/test"
let total = 16
for 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: - CocoaMQTTDelegate
extension 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 CocoaMQTT

class 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#_Toc3901059
let clientID = "ClientQuickStartTls"
mqtt = CocoaMQTT(clientID: clientID, host: host, port: port)
// 在控制台 --> 认证 Tab页创建账户, 复制用户名和密码
mqtt.username = "YOUR_USERNAME"
mqtt.password = "YOUR_PASSWORD"
mqtt.keepAlive = 60
mqtt.cleanSession = true
mqtt.autoReconnect = true
// 启用 SSL/TLS
mqtt.enableSSL = true
mqtt.allowUntrustCACertificate = false
// 设置代理
mqtt.delegate = self
// 连接到服务器
_ = mqtt.connect()
}
func publishMessages() {
// 确认一级主题 "home" 在MQTT控制台已经创建
let topic = "home/test"
let total = 16
for 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: - CocoaMQTTDelegate
extension 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
待发布消息的目标主题。
消息主题可以包含多级(level), 通过'/'隔开。第一级主题(Topic)需要在控制台 Topic Tab 页创建。详情参见 Topic Names and Topic Filters
topicFilters
一个或者多个订阅表达式。
订阅表达式可以包含通配符(Wildcards),详情参见 Topic Names and Topic Filters
qos
服务质量数组,数组长度必须与 Topic Filters 数据保持一致。
最常用的 QoS 为1, 即至少投递一次(At-Least-Once),详情参见 Quality of Service levels and protocol flows
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、产品序列号等。
合法的 Client Identifier 包含: 数字0-9, 小写英文字母 a-z, 大写英文字母 A-Z; 总长度为1-23个字符。详情参见 Client Identifier
username
连接用户名,在控制台集群详情页认证管理页面复制。



password
连接用户名匹配的密码,在控制台集群详情页认证管理页面复制。