emqx/CocoaMQTT

Điểm qua emqx/CocoaMQTT: 1.7k sao trên GitHub, viết chủ yếu bằng Swift, thuộc nhóm Mobile. MQTT 5.0 client library for iOS and macOS written in Swift
Tóm tắt dựng từ metadata GitHub của chính dự án — chưa có bài review TopGit. Trang sẽ tự động cập nhật khi bài review đầy đủ được xuất bản.
TopGit viết bài đầy đủ cho repo có nhiều sao nhất và được yêu cầu nhiều nhất. Trang này là snapshot trong thời gian chờ — xem README gốc ở tab READ ME.
Snapshot
Cộng tác viên hàng đầu
Xem cộng tác viên hàng đầu
CocoaMQTT
CocoaMQTT 2.x LTS: This branch contains the latest stable 2.x release line. It preserves the established CocoaAsyncSocket and Starscream transport architecture and receives compatibility, correctness, and security fixes. CocoaMQTT 3 development continues on
master. See the 2.x maintenance policy and changelog.
MQTT v3.1.1 and v5.0 client library for iOS/macOS/tvOS/visionOS written with Swift 5. visionOS is supported through Swift Package Manager.
Both Swift Package Manager products can be used by Swift 6 applications and are covered by a Swift 6 compatibility check in CI.
Build
The package manifest requires Swift tools 5.7. Release CI validates the current Xcode toolchain and Swift 6 compatibility; it does not independently exercise the oldest Swift 5.7 compiler. CocoaPods uses Swift 5 language mode.
IOS Target: 12.0 or above OSX Target: 10.13 or above TVOS Target: 12.0 or above with Swift Package Manager or CocoaPods WebSockets; 10.0 or above with CocoaPods Core visionOS Target: 1.0 or above (Swift Package Manager only, compile-verified in CI)
Installation
Swift Package Manager
To integrate CocoaMQTT into your Xcode project using Swift Package Manager, follow these steps:
- Open your project in Xcode.
- Go to
File>Swift Packages>Add Package Dependency. - Enter the repository URL:
https://github.com/emqx/CocoaMQTT.git. - Choose the latest version or specify a version range.
- Add the package to your target.
Swift Package Manager supports iOS, macOS, tvOS, and visionOS. Both the
CocoaMQTT and CocoaMQTTWebSocket products are compile-verified against the
visionOS SDK in CI.
At last, import "CocoaMQTT" to your project:
import CocoaMQTT
CocoaPods
To integrate CocoaMQTT into your Xcode project using CocoaPods, you need to modify you Podfile like the followings:
visionOS: CocoaPods installation is not currently supported because the transitive CocoaPods dependencies do not declare visionOS compatibility. Use Swift Package Manager for visionOS applications.
use_frameworks!
target 'Example' do
pod 'CocoaMQTT'
end
Then, run the following command:
$ pod install
At last, import "CocoaMQTT" to your project:
import CocoaMQTT
Usage
Create a client to connect MQTT broker:
///MQTT 5.0
let clientID = "CocoaMQTT-" + String(ProcessInfo().processIdentifier)
let mqtt5 = CocoaMQTT5(clientID: clientID, host: "broker.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 = CocoaMQTTMessage(topic: "/will", string: "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.emqx.io", port: 1883)
mqtt.username = "test"
mqtt.password = "public"
mqtt.willMessage = CocoaMQTTMessage(topic: "/will", string: "dieout")
mqtt.keepAlive = 60
mqtt.delegate = self
mqtt.connect()
Now you can use closures instead of CocoaMQTTDelegate:
mqtt.didReceiveMessage = { mqtt, message, id in
print("Message received in topic \(message.topic) with payload \(message.string!)")
}
TLS
Publicly trusted server certificate
Enable TLS for a broker whose certificate is rooted in the Apple system trust store. CocoaMQTT verifies the certificate against the broker host by default.
mqtt.enableSSL = true
When connecting to an IP address while the certificate is issued to a DNS name, set the certificate name explicitly:
mqtt.tlsServerName = "broker.example.com"
Private CA or self-signed CA
Load a DER or PEM encoded CA certificate and decide whether the system trust store should also be accepted:
let data = try Data(contentsOf: Bundle.main.url(forResource: "broker-ca", withExtension: "crt")!)
guard let certificate = CocoaMQTTSocket.serverCertificate(from: data) else {
fatalError("Invalid CA certificate")
}
mqtt.trustedServerCertificates = [certificate]
mqtt.usesSystemTrustStore = false // Trust only this CA.
mqtt.enableSSL = true
For advanced pinning or enterprise policies, set manuallyEvaluateTrust = true
and implement the trust delegate method or didReceiveTrust closure. Never
accept every certificate in production. The legacy
allowUntrustCACertificate property only enables this manual evaluation; it
does not safely trust a private CA by itself. Enabling manual evaluation without
a trust callback or custom CA certificates rejects the connection.
Mutual TLS
For TCP, create CocoaMQTT or CocoaMQTT5 normally. For WSS, use the
MQTT 3.1.1 WebSocket client
or MQTT 5 WebSocket client
example. CocoaMQTTWebSocket automatically uses Apple's
URLSessionWebSocketTask on macOS 10.15, iOS 13, tvOS 13, visionOS 1, and
later; no transport selection is required. Older supported OS versions
automatically fall back to Starscream, where clientIdentity does not
participate in the TLS handshake. Before calling connect(), apply either the
PEM/DER configuration
or PKCS#12 configuration.
Both configuration functions work with MQTT 3.1.1 and MQTT 5 over TCP or
WSS using URLSessionWebSocketTask, and configure the client identity and
broker trust separately.
Use their tlsServerName parameter when the connection host differs from the
DNS name in the broker certificate.
certificateData accepts a DER certificate, a single PEM certificate, or a PEM
bundle with the leaf first followed by its intermediates. privateKeyData
accepts RSA PKCS#1 (RSA PRIVATE KEY) or unencrypted RSA PKCS#8 (PRIVATE KEY)
input. Encrypted and EC PEM private keys are not currently supported. The
intermediate array is flattened in the supplied order after any certificates in
the leaf bundle; duplicates and a repeated leaf are ignored. Pass the leaf
issuer first and normally exclude the root. It is independent from
trustedServerCertificates, which validates the broker. The PEM/DER importer
requires macOS 10.14, iOS 12, tvOS 12, or visionOS 1. This API applies to the
built-in TCP transport and the Apple URLSessionWebSocketTask transport. The
older Starscream WebSocket fallback does not support client identities. Custom
transports can opt in by conforming to
CocoaMQTTClientIdentityConfiguring.
URLSessionWebSocketTask client identities are scoped to the original
WebSocket host and port. A client-certificate challenge is cancelled when no
clientIdentity is configured or after a cross-host redirect.
The same high-level TLS settings—tlsServerName,
trustedServerCertificates, usesSystemTrustStore, manuallyEvaluateTrust,
and clientIdentity—are available to the built-in TCP and
URLSessionWebSocketTask transports while preserving each transport's existing
callback flow. sslSettings remains a TCP-only low-level escape hatch. Client
identity and server trust remain independent. For WebSocket connections,
tlsServerName overrides certificate identity verification; the WebSocket URL
host still controls routing and TLS SNI.
PKCS#12 is a password-protected identity container supported by Apple's
SecPKCS12Import.
The example imports its identity and certificate chain, then uses the same
clientIdentity API as the PEM/DER path.
Do not ship a production unencrypted PEM private key in the application bundle. Do not embed a PKCS#12 file together with its password either. Obtain credentials through secure provisioning or user input, and keep long-lived secrets in Keychain-backed storage. The file format itself does not determine App Store eligibility; use supported Security framework APIs and protect the private key.
MQTT over WebSocket
CocoaMQTT supports connecting to MQTT brokers over WebSocket.
If you integrated by Swift Package Manager, follow these steps:
- Open your project in Xcode.
- Go to
File>Swift Packages>Add Package Dependency. - Enter the repository URL:
https://github.com/emqx/CocoaMQTT.git. - Choose the latest version or specify a version range.
- Add the
CocoaMQTTandCocoaMQTTWebSocketproducts to your target.
Import the CocoaMQTT products into your project:
import CocoaMQTT
import CocoaMQTTWebSocket
If you integrated by CocoaPods, update your Podfile as follows and run
pod install again:
use_frameworks!
target 'Example' do
pod 'CocoaMQTT/WebSockets'
end
If you're using CocoaMQTT in a project with only a .podspec and no Podfile, e.g. in a module for React Native, add this line to your .podspec:
Pod::Spec.new do |s|
...
s.dependency "CocoaMQTT/WebSockets"
end
Then, create an MQTT instance over WebSocket:
///MQTT 5.0
let websocket = CocoaMQTTWebSocket(uri: "/mqtt")
let mqtt5 = CocoaMQTT5(clientID: clientID, host: host, port: 8083, socket: websocket)
let connectProperties = MqttConnectProperties()
connectProperties.topicAliasMaximum = 0
// ...
mqtt5.connectProperties = connectProperties
// ...
_ = mqtt5.connect()
///MQTT 3.1.1
let websocket = CocoaMQTTWebSocket(uri: "/mqtt")
let mqtt = CocoaMQTT(clientID: clientID, host: host, port: 8083, socket: websocket)
// ...
_ = mqtt.connect()
The built-in Apple URLSessionWebSocketTask transport fails a receive when one
WebSocket message reaches its 1 MiB buffering limit. Set a value greater than
the largest expected WebSocket message before connecting, or use 0 to remove
the limit:
let websocket = CocoaMQTTWebSocket(uri: "/mqtt")
websocket.maximumMessageSize = 10 * 1024 * 1024 + 1 // Accept up to 10 MiB.
This setting is independent of MQTT 5 Maximum Packet Size. It is not used by
the older Starscream fallback, and custom connection builders must configure
their own transport. Use 0 only when message sizes are otherwise controlled,
because it permits unbounded buffering.
If you want to add additional custom header to the connection, you can use the following:
let websocket = CocoaMQTTWebSocket(uri: "/mqtt")
websocket.headers = [
"x-api-key": "value"
]
websocket.enableSSL = true
let mqtt = CocoaMQTT(clientID: clientID, host: host, port: 8083, socket: websocket)
// ...
_ = mqtt.connect()
If you want to connect using WebSocket Secure (wss), you can use the following example:
import CocoaMQTT
import CocoaMQTTWebSocket
class WebSocketManager {
private var mqttClient: CocoaMQTT?
var message: String = ""
var token: String = ""
func setupMQTTClient(with token: String) {
let socket = CocoaMQTTWebSocket(uri: "/mqtt")
socket.enableSSL = true
mqttClient = CocoaMQTT(clientID: token, host: "host", port: 443, socket: socket)
mqttClient?.delegate = self
}
func connect() {
guard let mqttClient = mqttClient else { return }
mqttClient.connect()
}
}
extension WebSocketManager: CocoaMQTTDelegate {
func mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) {
print("Published message with ID: \(id)")
}
func mqtt(_ mqtt: CocoaMQTT, didUnsubscribeTopics topics: [String]) {
print("Unsubscribed from topics: \(topics)")
}
func mqttDidPing(_ mqtt: CocoaMQTT) {
print("MQTT did ping")
}
func mqttDidReceivePong(_ mqtt: CocoaMQTT) {
print("MQTT did receive pong")
}
func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: (any Error)?) {
print("Disconnected from MQTT broker with error: \(String(describing: err))")
}
func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {
print("Connected to MQTT broker with acknowledgment: \(ack)")
}
func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {
if let messageString = message.string {
DispatchQueue.main.async {
self.message = messageString
}
print("Received message: \(messageString) on topic: \(message.topic)")
}
}
func mqtt(_ mqtt: CocoaMQTT, didPublishMessage message: CocoaMQTTMessage, id: UInt16) {
print("Published message: \(message.string ?? "") with ID: \(id)")
}
func mqtt(_ mqtt: CocoaMQTT, didSubscribeTopics success: NSDictionary, failed: [String]) {
print("Subscribed to topics: \(success), failed to subscribe to: \(failed)")
}
func mqtt(_ mqtt: CocoaMQTT, didDisconnectWithError err: Error?) {
print("Disconnected from MQTT broker with error: \(String(describing: err))")
}
}
Large outgoing messages
Socket writes have a five-second deadline by default. Increase it before publishing large messages on slower connections:
mqtt.socketWriteTimeout = 30
Set socketWriteTimeout to 0 or a negative value to disable the deadline.
This setting applies to MQTT 3.1.1 and MQTT 5 over the built-in TCP and
WebSocket transports. It does not override the broker's packet-size limit or
the MQTT 5 Server Maximum Packet Size. Prefer binary payloads or
application-level chunking when messages are large; Base64 increases their
encoded size.
Example App
You can follow the Example App to learn how to use it. But we need to make the Example App works first:
$ cd Examples
Then, open the Example.xcodeproj by Xcode and start it!
Dependencies
These third-party functions are used:
GCDAsyncSocket
- MqttCocoaAsyncSocket
- Starscream (legacy WebSocket fallback for older Apple OS versions)
LICENSE
MIT License (see LICENSE)
Contributors
- @andypiper
- @turtleDeng
- @jan-bednar
- @jmiltner
- @manucheri
- @Cyrus Ingraham
Author
- Feng Lee [email protected]
- CrazyWisdom [email protected]
- Alex Yu [email protected]
- Leeway [email protected]
https://twitter.com/EMQTech
Repo liên quan
A collaborative GitHub list linking to open-source apps across iOS, iPadOS, watchOS, tvOS, and visionOS, grouped into categories like Browser, Communication, and Clone, with each entry tagged by year and language.
BitChat is a mesh chat app for iOS and macOS that routes messages over Bluetooth LE when you're offline and falls back to the Nostr protocol when you have signal, with no phone number, account, or central server involved. It's built for people who want to text nearby without cell service — a protest, a festival, a dead zone — and its own whitepaper is upfront about where the privacy model still has gaps, like a persistent per-device identifier and store-and-forward messages that skip forward secrecy.
Flutter is Google's open-source SDK, hosted at flutter/flutter on GitHub, for building user interfaces across mobile, web, and desktop from a single Dart codebase. The repo is licensed BSD-3-Clause, and its README documents stateful hot reload, a Skia/Impeller rendering pipeline, and Material/Cupertino widget sets as the core pieces developers work with.
Free Programming Books (Chinese) is justjavac's GitHub index of free programming books, translated manuals, and course notes in Chinese, organized under headings like AI, Go, C/C++, and version control. It's a link list, not a curriculum - entries range from full book translations to single blog posts, some flagged `:worried:` for dead links, and contribution happens only through pull requests.
Trả lời nhanh
Cùng nhóm Mobile còn repo nào?
emqx/CocoaMQTT thuộc nhóm Mobile trên TopGit, cùng 9 topic GitHub. Trang Trending và Topics liệt kê các repo cùng số sao và cùng ngôn ngữ để so sánh.
Đọc thêm về emqx/CocoaMQTT ở đâu?
Trang TopGit này là một snapshot — tab "Readme" hiển thị nguyên văn README của repo (đã bỏ link, giữ ảnh). Repo GitHub ở github.com/emqx/CocoaMQTT là nguồn chính thức.
emqx/CocoaMQTT có bao nhiêu sao?
emqx/CocoaMQTT có 1.7k sao GitHub — tải lại trang để xem số mới nhất, hoặc xem trực tiếp github.com/emqx/CocoaMQTT. TopGit phản chiếu số sao của GitHub nhưng không cam kết đến từng phút.
emqx/CocoaMQTT có những chủ đề gì?
GitHub topics của emqx/CocoaMQTT: "cocoamqtt", "cocoapods", "ios", "macos", "macosx", "mqtt", "mqtt-client", "swift", "tvos". TopGit xếp repo vào nhóm Mobile.
emqx/CocoaMQTT còn đang phát triển không?
Commit gần nhất trên emqx/CocoaMQTT là 23 ngày trước (theo timestamp GitHub). Repo có 474 fork — một chỉ báo về mức độ quan tâm của cộng đồng.
emqx/CocoaMQTT viết bằng ngôn ngữ gì?
emqx/CocoaMQTT chủ yếu viết bằng Swift. Trường "language" của GitHub dựa trên phần lớn byte ở nhánh mặc định.
Vì sao emqx/CocoaMQTT được xếp vào nhóm Mobile?
TopGit xếp emqx/CocoaMQTT vào nhóm Mobile dựa trên GitHub topics và mô tả của repo (gắn thẻ: "cocoamqtt", "cocoapods", "ios"). Việc phân loại dựa trên metadata thật của repo, không phải đoán theo cảm tính biên tập.
Đọc đầy đủ README ở tab phía trên.
Chưa chắc CocoaMQTT có hợp với bạn?
Để ChatGPT, Claude hoặc Perplexity tìm hiểu giúp — bấm bên dưới và xem AI nói gì về CocoaMQTT.