首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在iOS Swift中应用程序在后台时如何通过MQTT客户端框架发布或发送消息

在iOS Swift中应用程序在后台时如何通过MQTT客户端框架发布或发送消息
EN

Stack Overflow用户
提问于 2020-09-16 22:04:11
回答 1查看 407关注 0票数 0

我正在开发一个应用程序,通过MQTT客户端框架每15分钟发送一次当前用户位置。当应用程序在前台时,它可以正常工作,但当应用程序在后台时,MQTT委托函数"messageDelivered“不会被调用

我们希望在iOS swift中使用MQTT客户端框架在后台发布消息。

代码语言:javascript
运行
复制
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")
}
EN

Stack Overflow用户

发布于 2020-09-16 22:16:24

我们已经在后台实现了更新位置,所以使用更新位置来更新您的代码,以便在后台发送消息。

代码语言:javascript
运行
复制
import UIKit
import CoreLocation
@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate,CLLocationManagerDelegate {
var window: UIWindow?
var locationManager = CLLocationManager()
var backgroundUpdateTask: UIBackgroundTaskIdentifier!
var bgtimer = Timer()
var latitude: Double = 0.0
var longitude: Double = 0.0
var current_time = NSDate().timeIntervalSince1970
var timer = Timer()
var f = 0
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    self.doBackgroundTask()
    return true
}


func applicationWillResignActive(_ application: UIApplication) {
}

func applicationWillEnterForeground(_ application: UIApplication) {
    print("Entering foreBackground")
}

func applicationDidBecomeActive(_ application: UIApplication) {
}

func applicationWillTerminate(_ application: UIApplication) {
}

func applicationDidEnterBackground(_ application: UIApplication) {
    print("Entering Background")
   // self.doBackgroundTask()
}

func doBackgroundTask() {

    DispatchQueue.main.async {

        self.beginBackgroundUpdateTask()

        self.StartupdateLocation()


        self.bgtimer = Timer.scheduledTimer(timeInterval:-1, target: self, selector: #selector(AppDelegate.bgtimer(_:)), userInfo: nil, repeats: true)
        RunLoop.current.add(self.bgtimer, forMode: RunLoopMode.defaultRunLoopMode)
        RunLoop.current.run()

        self.endBackgroundUpdateTask()

    }
}

func beginBackgroundUpdateTask() {
    self.backgroundUpdateTask = UIApplication.shared.beginBackgroundTask(expirationHandler: {
        self.endBackgroundUpdateTask()
    })
}

func endBackgroundUpdateTask() {
    UIApplication.shared.endBackgroundTask(self.backgroundUpdateTask)
    self.backgroundUpdateTask = UIBackgroundTaskInvalid
}

func StartupdateLocation() {
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.distanceFilter = kCLDistanceFilterNone
    locationManager.requestAlwaysAuthorization()
    locationManager.allowsBackgroundLocationUpdates = true
    locationManager.pausesLocationUpdatesAutomatically = false
    locationManager.startUpdatingLocation()
}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    print("Error while requesting new coordinates")
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    let locValue:CLLocationCoordinate2D = manager.location!.coordinate

    self.latitude = locValue.latitude
    self.longitude = locValue.longitude
    f+=1
    print("New Coordinates: \(f) ")
    print(self.latitude)
    print(self.longitude)
}

@objc func bgtimer(_ timer:Timer!){
    sleep(2)
  /*  if UIApplication.shared.applicationState == .active {
         timer.invalidate()
    }*/
    self.updateLocation()
}

func updateLocation() {
    self.locationManager.startUpdatingLocation()
    self.locationManager.stopUpdatingLocation()
}}
票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63921790

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档