Connecting to MQTT in Swift & IOS
MQTT is a Message Queuing Telemetry Transport protocol, it is also called MQ Telemetry Transport. It is widely used in IOT (Internet of Things) to have a good connectivity between machine and machines (machine-to-machine M2M). It is designed to be extremely lightweight to publish/subscribe messaging transport. It is useful for connections with remote locations where a small code footprint is required and/or network bandwidth is at a premium. It is widely used in different areas like sensor communications, satellite broker link, dialup connection, healthcare providers and home automations. It is extremely ideal for Mobile Application because of its light weight, low power usage and minimised data packets.. For more information about MQTT visit Here.
I recently had a chance to implement it to one of the smart home application i developed, Therefore i thought of sharing my experience relate to development. I have implemented this Protocol to my IOS application using Swift programming language.
Instruction to implement MQTT
One of the MQTT library available for IOS is called Moscapsule Visit Here
Lets get started……………..
Add these two lines to your podfile
1 2 |
pod 'Moscapsule', :git => 'https://github.com/flightonary/Moscapsule.git' pod 'OpenSSL-Universal' |
run the command pod install. Then close and open your .workspace file
Now you have the Moscapules added to you project, open your AppDelegate.swift file and ad the following codes. You can see the comments inside the code itself
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
// Import the library Moscapsule import Moscapsule func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // call the implemeted method inside didFinishLaunchingWithOptions StartMQTT() return true } func StartMQTT() -> Void { moscapsule_init() //set MQTT client configuration let RandomId : String = "IOS_\(UIDevice.current.identifierForVendor!.uuidString)" let mqttConfig = MQTTConfig(clientId: RandomId, host: "192.168.1.1", port: 1883, keepAlive: 60) mqttConfig.mqttAuthOpts = MQTTAuthOpts(username: "sathyabaman", password: "test123") mqttConfig.onPublishCallback = { messageId in print("published (msg id=\(messageId)))") } // Receive published message here mqttConfig.onMessageCallback = { mqttMessage in print("MQTT Message received: payload=\(mqttMessage.payloadString ?? "no value")") let receivedMessage = mqttMessage.payloadString! let receivedTopic = mqttMessage.topic print("**************************************************************************************************************************************") print("Topic : \(receivedTopic)") print("--------------------------------------------------------") print(receivedMessage) print("**************************************************************************************************************************************") let data = receivedMessage.data(using: .utf8, allowLossyConversion: false)! print("xxxxxxx = \(data)") self.DoBroadCast(Topic: receivedTopic, Message: receivedMessage) } mqttConfig.onSubscribeCallback = { (messageId, grantedQos) in NSLog("MQTT subscribed (mid=\(messageId),grantedQos=\(grantedQos))") } mqttConfig.onPublishCallback = { messageId in NSLog("published (mid=\(messageId))") } // Connecting to Mqtt server mqttClient = MQTT.newConnection(mqttConfig, connectImmediately: true) } //Subscribing to Topics func subscribeToTopic() -> Void { let hubId = UserDefaults.standard.value(forKey: "hubID") as? String let userId = UserDefaults.standard.value(forKey: "user_id") as? String let Topic :String = "/vq/smart/"+hubId!+"/"+userId!+"/rest/" let hubTopic :String = "/vq/smart/"+hubId!+"/rest/" mqttClient?.subscribe(Topic, qos: 1) mqttClient?.subscribe(hubTopic, qos: 1) } // Check MQTT connection status func CheckMQTTConnectionStatus() -> Bool { print("MQTT Connection Status : \(String(describing: mqttClient?.isConnected))") return (mqttClient?.isConnected)! } |
Thats it, Its very simple to connect, Since you have implemented this code in you AppDelegate, You can start the connection from anywhere inside the application by calling
1 2 |
let appDelegate = UIApplication.shared.delegate as! AppDelegate appDelegate. StartMQTT() |
You can check connection and subscribe to topics
1 2 3 |
if appDelegate.CheckMQTTConnectionStatus(){ appDelegate.subscribeToTopic(); } |
The best way to send to your view controllers is buy Broadcasting the received message in onMessageCallback . Here is how i have done it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
func DoBroadCast(Topic: String, Message: String) -> Void { let hubId = UserDefaults.standard.value(forKey: "hubID") as? String let userId = UserDefaults.standard.value(forKey: "user_id") as? String let members :String = "/vq/smart/"+hubId!+"/"+userId!+"/rest/octopus/" let hubTopic :String = "/vq/smart/"+hubId!+"/rest/" switch Topic { case members: DispatchQueue.main.async() { let data = [ "Topic" : Topic , "message": Message ] as [String : Any] let notificationName = Notification.Name("ReloadSensorList") NotificationCenter.default.post(name: notificationName, object: nil, userInfo: data) } break case hubTopic: DispatchQueue.main.async() { let data = [ "Topic" : Topic , "message": Message ] as [String : Any] let notificationName = Notification.Name("ReloadSensorList") NotificationCenter.default.post(name: notificationName, object: nil, userInfo: data) } break default: break } } |
You can add a broadcast receiver to you ViewController so that you can receive this broadcast
1 2 3 4 5 6 7 8 9 10 11 12 13 |
override func viewDidLoad() { NotificationCenter.default.addObserver(self, selector: #selector(notificationReceived(_:)), name: NSNotification.Name(rawValue: "ReloadSensorList"), object: nil) } func notificationReceived(_ notification: NSNotification) { if let topic = notification.userInfo?["Topic"] as? String { print(topic) } if let message = notification.userInfo?["message"] as? String { print(message) } } |
Thats it, Its very simple. Hope this helps for someone.
If you have any Question or suggestions please leave it below in the comments section. Happy Coding 🙂 . Enjoy MQTT
MesAlkaw
🙂🙂🙂
PesAlkaw
🙂🙂🙂