iOS中的MQTT

为什么和如何

什么是MQTT?

MQTT是一种轻量级协议,用于将消息从设备传输到客户端。 作为对MQTT的非常简短的描述,它通过具有充当中间人的MQTT代理来操作。 该代理管理一个或多个主题,这些主题是消息可能涉及的主题。 设备可以从那里将消息发布到某个主题,并且订阅该主题的所有连接的客户端都将收到该消息。

如果您以前从未使用过MQTT,则仅靠简要概述可能还不够,您可以在此处找到更详细的MQTT描述。

MQTT的用途

MQTT之所以出色,是因为它允许设备以相对较低的开销成本将数据发布到客户端,从而使其成为物联网设备的首选协议。 结果,您可能会发现自己想要在智能手机应用程序中实现MQTT,以允许移动访问此类IOT设备的数据。

当然,这可以应用于多种情况,但是在我的特殊情况下,我有一个传感器每秒大约发布一次读数。 我的目标是在我正在构建的应用程序中显示这些实时读数,因此本文将基于该特定应用程序,但当然仍可以应用于涉及iOS中MQTT的各种应用程序。

当然,它不仅可以显示原始消息,还可以进一步发展,并且您可以决定创建一个包含文本和图像的更加精致的界面,以更吸引人的方式解释和显示传入的MQTT消息。 您也可以根据需要决定使用实时MQTT数据发送通知,这将在以后的文章中进行介绍。

幸运的是,将MQTT数据的实时流传输到iOS应用程序上非常简单。

MQTT库

您将需要一个库才能将MQTT与iOS应用程序一起使用,因此我建议使用CocoaMQTT。 CocoaMQTT是“ pod”,这意味着它是使用CocoaPods进行管理和安装的。 通过第一个链接,您将找到设置和使用说明,但是在这里,我将显示必要的部分以使其变得更容易。

要使用CocoaMQTT,您将需要使用CocoaPods设置项目。 要做到这一点:

  1. 打开终端
  2. cd进入项目的根文件夹
  3. 运行“ pod init”

这将创建一个名为“ Podfile”的文件。从此处开始,您需要编辑该“ podfile”以包含CocoaMQTT。 为此,请在您选择的编辑器中打开文件并添加以下内容:

 豆荚'CocoaMQTT' 

Podfile现在应如下所示:

  #取消注释下一行以定义项目的全局平台 
#platform:ios,'9.0'
 目标'MQTTExample'做 
#如果您不使用Swift并且不想使用动态框架,请注释下一行
use_frameworks!
  #MQTT的豆荚示例 
豆荚'CocoaMQTT'

结束

当然,目标名称可能会有所不同,具体取决于您为项目命名的名称。 从那里开始运行pod install ,CocoaPods将安装CocoaMQTT。 CocoaPods还将创建一个新文件“ MQTTExample.xcworkspace”,您现在必须使用它来代替xcodeproj文件。 打开该工作区,是时候添加CocoaMQTT了。

设置

要设置基本应用程序,只需在主故事板的中央放置一个标签,然后在视图控制器中创建一个插座即可。 到目前为止,您应该具有以下内容:

您可以在以后使界面更加精美,但这现在就可以了。

实施MQTT

现在,我们需要设置ViewController来建立MQTT连接并处理所有接收到的消息。 在此应用程序中,目标是在主视图的标签中显示任何收到的消息。

设置连接

首先,您需要在文件顶部添加import CocoaMQTT

我们需要创建一个函数setUpMQTT()来处理MQTT连接的创建。 该代码直接来自CocoaMQTT的用法说明,但是使用当前语法进行了更新,并为此演示目的进行了修改:

  func setUpMQTT(){ 
让clientID =“ CocoaMQTT-” +字符串(ProcessInfo()。processIdentifier)
mqtt = CocoaMQTT(clientID:clientID,主机:“ localhost”,端口:1883)
mqtt.username =“测试”
mqtt.password =“公共”
mqtt.willMessage = CocoaMQTTWill(topic:“ / will”,消息:“ dieout”)
mqtt.keepAlive = 60
mqtt.connect()
}

您还需要添加var mqtt: CocoaMQTT! 在您的类的顶部创建mqtt变量。

以后您可以编辑主机和端口以适合项目所需,因此只要准备就绪就可以将其换出。 现在,只需将setUpMQTT()添加到viewDidLoad()函数即可在应用启动时设置连接。

创建代表

现在我们已经建立了连接,我们需要订阅一个主题并通过在标签中显示它们来处理所有传入消息。 为此,ViewController必须是CocoaMQTTDelegate。 我将通过扩展进行此操作,因为它对我而言看起来最干净。 这个扩展将包含很多方法,这些方法是为了符合CocoaMQTTDelegate协议所必需的,但是我们实际上只关心前两个:didConnect和didReceiveMessage。

 扩展ViewController:CocoaMQTTDelegate { 
//这两个方法是我们目前所关心的
func mqtt(_ mqtt:CocoaMQTT,didConnect主机:字符串,端口:整数){
}

func mqtt(_ mqtt:CocoaMQTT,didReceiveMessage消息:CocoaMQTTMessage,id:UInt16){
}

// CocoaMQTTDelegate的其他必需方法
func mqtt(_ mqtt:CocoaMQTT,didReceive信任:SecTrust,complementHandler:@转义(Bool)->无效){
completeHandler(true)
}

func mqtt(_ mqtt:CocoaMQTT,didConnectAck ack:CocoaMQTTConnAck){
}

func mqtt(_ mqtt:CocoaMQTT,didPublishMessage消息:CocoaMQTTMessage,id:UInt16){
}

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

func mqtt(_ mqtt:CocoaMQTT,didSubscribeTopic主题:字符串){
}

func mqtt(_ mqtt:CocoaMQTT,didUnsubscribeTopic主题:字符串){
}

func mqttDidPing(_ mqtt:CocoaMQTT){
}

func mqttDidReceivePong(_ mqtt:CocoaMQTT){
}

func mqttDidDisconnect(_ mqtt:CocoaMQTT,withError err:Error?){
}

func _console(_ info:String){
}
}

将其粘贴到ViewController类下方后,需要将ViewController设置为mqtt连接的委托,您可以通过将以下内容添加到setUpMQTT函数中来实现。

  mqtt.delegate =自我 

订阅主题

我发现最好在didConnect函数中订阅适当的主题。 这样,您仅在建立连接后订阅主题,并且不会在连接存在之前尝试订阅而遇到问题。 因此,将以下内容添加到didConnect方法中:

  mqtt.subscribe(“ testTopicName”) 

当然,您订阅的主题名称可以是您喜欢的任何名称,但是在此示例中,我将使用“ testTopicName”。

接收讯息

既然我们已经订阅了适当的主题,我们现在就可以处理从MQTT代理接收消息。 在这种情况下,我们希望将标签文本设置为接收到的消息的字符串。 我们可以使用以下代码在didReceiveMessage方法中执行此操作:

 如果让msgString = message.string { 
mqttLabel.text = msgString
}

瞧!

现在,该应用程序已设置为在标签中显示来自MQTT代理的所有消息。 最终,CocoaMQTT是解决该问题的方法。

在这里,您当然可以通过添加一些颜色,也许还添加一些标签,甚至根据接收到的消息而变化的图像来为其增添色彩。

就我而言,我进一步在后台获取期间建立了MQTT连接,以便在必要时发送通知。 我计划在以后的文章中也介绍该过程,因此如果您感兴趣,请保持更新。