I am developing an application to send the current user location every 15 minutes via the MQTT client framework. When the application is in the foreground it works fine but when the application is in background, the MQTT delegate function "messageDelivered" doesn't get called
We want to use the MQTT client framework to publish message in background in iOS swift.
import UIKit
import MQTTClient
class MainViewController: UIViewController {
let MQTT_HOST = "next.nanolink.com" // or IP address e.g. "192.168.0.194"
//let MQTT_HOST = "tnclicks.free.beeceptor.com" // or IP address e.g. "192.168.0.194"
let MQTT_PORT: UInt32 = 1883
private var transport = MQTTCFSocketTransport()
fileprivate var session = MQTTSession()
fileprivate var completion: (()->())?
override func viewDidLoad() {
super.viewDidLoad()
//notification observer
NotificationCenter.default.addObserver(self, selector: #selector(onDidReceiveData(_:)), name: .didReceiveData, object: nil)
//MQTT
self.session?.delegate = self
self.transport.host = MQTT_HOST
self.transport.port = MQTT_PORT
session?.transport = transport
updateUI(for: self.session?.status ?? .created)
session?.connect() { error in
print("connection completed with status \(String(describing: error?.localizedDescription))")
if error != nil {
self.updateUI(for: self.session?.status ?? .created)
} else {
self.updateUI(for: self.session?.status ?? .error)
}
}
}
private func subscribe() {
self.session?.subscribe(toTopic: "test/message", at: .exactlyOnce) { error, result in
print("subscribe result error \(String(describing: error)) result \(result!)")
}
}
private func updateUI(for clientStatus: MQTTSessionStatus) {
DispatchQueue.main.async {
switch clientStatus {
case .connected:
print("Connected")
self.publishMessage("on", onTopic: "test/message")
case .connecting,
.created:
print ("Trying to connect...")
default:
print ("Connetion Failed...")
}
}
}
private func publishMessage(_ message: String, onTopic topic: String)
{
session?.publishData(message.data(using: .utf8, allowLossyConversion: false), onTopic: topic, retain: false, qos: .exactlyOnce)
}
@objc func onDidReceiveData(_ notification:Notification) {
print("check return")
guard session?.status == .connected else {
self.updateUI(for: self.session?.status ?? .error)
return
}
let obj = notification.object! as! NSMutableDictionary
print(notification.object!)
let notificationLatitude = obj.value(forKey: "latitude")!
let notificationLongitude = obj.value(forKey: "longitude")!
//let notificationLongitude = notification.object
// print(" Saved latitude:", latitude!)
// print(" Saved longitude:", longitude!)
print(" notification latitude:", notificationLatitude)
print(" notification longitude:", notificationLongitude)
guard session?.status == .connected else {
return
}
publishMessage("on", onTopic: "test/message")
}
}
extension MainViewController: MQTTSessionManagerDelegate, MQTTSessionDelegate {
func newMessage(_ session: MQTTSession!, data: Data!, onTopic topic: String!, qos: MQTTQosLevel, retained: Bool, mid: UInt32) {
if let msg = String(data: data, encoding: .utf8) {
print("topic \(topic!), msg \(msg)")
}
}
func messageDelivered(_ session: MQTTSession, msgID msgId: UInt16) {
print("delivered")
DispatchQueue.main.async {
self.completion?()
}
}
}
extension Notification.Name {
static let didReceiveData = Notification.Name("didReceiveData")
}