如何通过不断更新MQTT发布者的数据来更新UILabel?

时间:2018-02-10 21:52:04

标签: ios swift event-handling mqtt

我有一个带有温度传感器的Raspberry Pi,它有一个python脚本,它不断使用MQTT发布温度,我已经设置了每1秒的间隔。在我正在制作的iOS应用程序中,我有一个MQTTManager类,它有一个mqttClient,可以订阅它的主题并接收带有温度的字符串。在我的应用程序的主视图中,我想显示温度并让它不断更新,与python脚本发送它的速度相同(或接近相同)。到目前为止,我的想法是使用mqtt客户端消息中的消息字符串更新UILabel的文本。我不确定如何正确更新标签文本,每次发送的发布事件。我知道我需要为此消息设置某种事件处理程序,但我不知道如何去做。任何帮助将不胜感激。

更新:使用我到目前为止的代码。这是我的mqttManager:

//
//  MQTTManager.swift
//  TemperatureApp
//
//  Created by Radoka on 2/10/18.
//  Copyright © 2018 radoslav.genov.1992. All rights reserved.
//

    import UIKit
    import CocoaMQTT

    class MQTTManager: NSObject, CocoaMQTTDelegate {

    static let singleton = MQTTManager()
    let mqttClient = CocoaMQTT(clientID: "iOS Device Emulator", host: "192.168.0.101", port: 1883)
    var connected = false

    override init() {
        super.init()
        print("MQTT Initilalized")
        mqttClient.username = "user"
        mqttClient.password = "pass"
        mqttClient.keepAlive = 60
        mqttClient.delegate = self
        connect()
    }

    public func connect(){
        if mqttClient.connState != .connected && mqttClient.connState != .connecting {
            mqttClient.connect()
        }
      }

}

extension MQTTManager {
    func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {
        //nothing
    }

    func mqtt(_ mqtt: CocoaMQTT, didPublishMessage message: CocoaMQTTMessage, id: UInt16) {
        //nothing
    }

    func mqtt(_ mqtt: CocoaMQTT, didPublishAck id: UInt16) {
        //nothing
    }

    func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {
        if let string = message.string {
            print(string)
        }
    }

    func mqtt(_ mqtt: CocoaMQTT, didSubscribeTopic topic: String) {
        print("Subscribed to topic: ", topic)
    }

    func mqtt(_ mqtt: CocoaMQTT, didUnsubscribeTopic topic: String) {

    }

    func mqttDidPing(_ mqtt: CocoaMQTT) {
        print("PING")
    }

    func mqttDidReceivePong(_ mqtt: CocoaMQTT) {
        print("PONG")
    }

    func mqttDidDisconnect(_ mqtt: CocoaMQTT, withError err: Error?) {
        print("Disconnected with error: ", err!)
    }

    func mqtt(mqtt: CocoaMQTT, didConnect host: String, port: Int) {
        print("Connected to MQTT server.")
        connected = true
    }

    func subscribeToTopic(topic: String) {
        if mqttClient.connState == .connected {
            print("Subscribe to: ", topic)
            mqttClient.subscribe(topic, qos: CocoaMQTTQOS.qos1)
        } else {
            print("Can't subscribe to \(topic). Not connected.")
        }
    }
}

接下来这是我的MainTableViewController,其中我有mqttManager的共享实例:

//
//  MainTableViewController.swift
//  TemperatureApp
//
//  Created by Radoka on 2/9/18.
//  Copyright © 2018 radoslav.genov.1992. All rights reserved.
//

import UIKit
import CocoaMQTT
import CoreData


class MainTableViewController: UITableViewController {

    // MARK: - Table view data source
    @IBOutlet weak var temperature: UILabel!
    let mqttManager = MQTTManager.singleton 
    var container: NSPersistentContainer? = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer


    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }

    @IBAction func connectionTest(_ sender: UISwitch) {
        if sender.isOn {
            mqttManager.connect()
            print("connected")
            mqttManager.subscribeToTopic(topic: "rpi/gpio")
        } else {
            print("not connected")
        }
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return 3
    }

    public func setTemperature(){
        //Update text of temperature label 
    }

}

在设定温度方法中,我想更新文本标签。这是正确的做事方式吗?

1 个答案:

答案 0 :(得分:3)

我认为你可以用一个简单的Notification来解决它。 首先,您应该添加一个想要更新此类标签的观察者,这样做:

class MainTableViewController: UITableViewController {
   override func viewDidLoad() {
      super.viewDidLoad()

      // observe temperature
      NotificationCenter.default.addObserver(forName: NSNotification.Name.init("post_temperature"), object: nil, queue: OperationQueue.main) { [weak self] (notification) in
        self?.temperature.text = notification.object as? String ?? ""
      }
   }
}

然后当您收到主题的更新温度时,您应该致电:

extension MQTTManager {
   func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {
      if let string = message.string {
          // post temperature
          NotificationCenter.default.post(name: NSNotification.Name.init("post_temperature"), object: string)
      }
   }
}