我有一个带有温度传感器的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
}
}
在设定温度方法中,我想更新文本标签。这是正确的做事方式吗?
答案 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)
}
}
}