博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Swift使用XMPPFramework做IM即时通信的Demo
阅读量:4261 次
发布时间:2019-05-26

本文共 6808 字,大约阅读时间需要 22 分钟。

Swift使用XMPPFramework做IM即时通信的Demo

一篇文章处理了文本中表情的替换,现在来完成消息的发送功能吧(貌似前后并没有逻辑关系哈)


首先为了测试,我们需要下载spark工具,它可以连接openfire搭建的后台来完成即时通信的功能,方便测试。

博主这里用的是Spark 2.8.3,各位可以根据自己所使用的平台不同选择对应的客户端下载。由于目前只是做移动端开发,所以后台的搭建各位可以自行google。


使用Swift连接openfire服务端,可以使用XMPPFramework框架(同android端的smack类似)。大家可以选择手动导入,也可以使用cocoapod导入。博主懒,就用了cocoapod

这里写图片描述

现在的XMPPFramework已经支持了Swift,所以只需在要使用的controller中导入即可,不需要再建立桥接文件了。

import XMPPFramework
  • 1

准备工作都做得差不多了,接下来就开始真正的工作吧。

连接服务器

/// xmpp流var xmppStream: XMPPStream!
  • 1
  • 2
/// 连接服务器func connect() {    if xmppStream == nil {        xmppStream = XMPPStream()        /// 设置代理        xmppStream.addDelegate(self, delegateQueue: DispatchQueue.main)    }    if !xmppStream.isConnected() {        //用户名        let username = "ave2"         /// 初始化一个jid,resource可以为空        let jid = XMPPJID(user: username, domain: 域名, resource: nil)        xmppStream.myJID = jid        do {            /// 连接服务器            try xmppStream.connect(withTimeout: 5)        } catch let error {            print(error)        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

因为我们这里设置了代理,所以控制器需要遵循XMPPStreamDelegate协议

在连接成功后会调用回调方法

/// 连接服务器的回调func xmppStream(_ sender: XMPPStream!, socketDidConnect socket: GCDAsyncSocket!) {    print("连接成功")}
  • 1
  • 2
  • 3
  • 4

登陆

我们还可以在回调方法中输入密码来登陆账号

/// 连接成功后使用密码登陆func xmppStreamDidConnect(_ sender: XMPPStream!) {    print("ok")    do {        try sender.authenticate(withPassword: 密码)    } catch let error {        print(error)    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

当登陆成功后,会调用登陆成功的回调方法,我们可以在登陆成功的回调方法中设置登陆状态

/// 用户登陆成功func xmppStreamDidAuthenticate(_ sender: XMPPStream!) {    print("登陆成功")    let presence = XMPPPresence(type: "available")    xmppStream.send(presence)}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

用户的登陆状态分别有以下几种:

available 上线
away 离开
do not disturb 忙碌
unavailable 下线

退出

既然有登陆,那我们就需要实现退出功能

/// 退出登陆并断开连接@objc func disconnect() {    let presence = XMPPPresence(type: "unavailable")    xmppStream.send(presence)    ///断开连接    xmppStream.disconnect()}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

设置退出很简单,我们只需要把状态设置为下线即可,大家也可以不用在这个方法中设置断开连接,毕竟我们有时退出是为了更换账号呢(这里只是为了方便演示)

同样,退出也有回调方法

/// 退出登陆的回调func xmppStreamDidDisconnect(_ sender: XMPPStream!, withError error: Error!) {    print("退出成功")}
  • 1
  • 2
  • 3
  • 4

接收消息

有了登陆和退出功能,现在就是消息的接收和发送了,因为接收消息比较简单,所以我们就先说明接收消息的方法吧。

/// 成功接收消息func xmppStream(_ sender: XMPPStream!, didReceive message: XMPPMessage!) {    let text = message.body()    if text != nil {        label.text = text    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

接收的消息默认都存在message的body方法当中,我们只需要取出,然后对其进行相应的操作即可。奇怪的是,发送一条消息,这个接收消息的回调方法会调用三次,第一次和第三次会输出nil,只有第二次输出的才是有消息的内容,各位可以尝试打印输出。

发送消息

最后来实现发送消息吧,

因为发送消息需要指定发送的对象,我们这里就指定私聊的名为ave1的用户吧

/// 发送消息@objc func send() {    print("发送消息")    ///创建目的用户的jid    let jid = XMPPJID(user: "ave1", domain: 域名, resource: nil)    ///创建消息    let message = XMPPMessage(type: "chat", to: jid)    ///添加消息内容    message?.addBody("hello")    ///发送消息    xmppStream.send(message)}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在成功发送消息之后,同样也有一个回调方法

/// 成功发送消息func xmppStream(_ sender: XMPPStream!, didSend message: XMPPMessage!) {    print("成功发送消息 \(message.body())")}
  • 1
  • 2
  • 3
  • 4

对了,到此就完成了一个最最简单的使用基于openfire的XMPPFramework框架的IM即时通信功能了。

如果还想了解更多,可以欣赏一下


最后,还是贴一下演示效果和所有的代码吧

这里写图片描述

这里写图片描述

在这里呢,博主随便搭了一个简单的界面来演示效果(最上的label显示接收到的消息,左边的发送按钮发送消息–每次都是发送hello,右边的退出按钮退出登录并断开连接)

这里是所有的代码

import UIKitimport XMPPFrameworkclass ViewController: UIViewController {    /// 接收消息的标签    var label: UILabel!    /// xmpp流    var xmppStream: XMPPStream!    override func viewDidLoad() {        super.viewDidLoad()        // Do any additional setup after loading the view, typically from a nib.        setup()        connect()    }    /// 连接服务器    func connect() {        if xmppStream == nil {            xmppStream = XMPPStream()            /// 设置代理            xmppStream.addDelegate(self, delegateQueue: DispatchQueue.main)        }        if !xmppStream.isConnected() {            //用户名            let username = "ave2"            /// 初始化一个jid,resource可以为空            let jid = XMPPJID(user: username, domain: 域名, resource: nil)            xmppStream.myJID = jid            do {                /// 连接服务器                try xmppStream.connect(withTimeout: 5)            } catch let error {                print(error)            }        }    }    /// 退出登陆并断开连接    @objc func disconnect() {        let presence = XMPPPresence(type: "unavailable")        xmppStream.send(presence)        xmppStream.disconnect()    }    /// 构建界面    func setup() {        label = UILabel(frame: CGRect(x: 100, y: 50, width: 200, height: 500))        label.textColor = UIColor.black        label.text = "hello"        label.textAlignment = .center        label.layer.borderWidth = 1        label.numberOfLines = 0        self.view.addSubview(label)        let button = UIButton(frame: CGRect(x: 100, y: 600, width: 90, height: 44))        button.setTitle("发送", for: .normal)        button.setTitleColor(UIColor.black, for: .normal)        button.layer.borderWidth = 1        button.addTarget(self, action: #selector(send), for: .touchUpInside)        self.view.addSubview(button)        let button1 = UIButton(frame: CGRect(x: 210, y: 600, width: 90, height: 44))        button1.setTitle("退出", for: .normal)        button1.setTitleColor(UIColor.black, for: .normal)        button1.layer.borderWidth = 1        button1.addTarget(self, action: #selector(disconnect), for: .touchUpInside)        self.view.addSubview(button1)    }    /// 发送消息    @objc func send() {        print("发送消息")        ///创建目的用户的jid        let jid = XMPPJID(user: "ave1", domain: 域名, resource: nil)        ///创建消息        let message = XMPPMessage(type: "chat", to: jid)        ///添加消息内容        message?.addBody("hello")        ///发送消息        xmppStream.send(message)    }    override func didReceiveMemoryWarning() {        super.didReceiveMemoryWarning()        // Dispose of any resources that can be recreated.    }}extension ViewController: XMPPStreamDelegate {    /// 连接服务器的回调    func xmppStream(_ sender: XMPPStream!, socketDidConnect socket: GCDAsyncSocket!) {        print("连接成功")    }    /// 连接成功后使用密码登陆    func xmppStreamDidConnect(_ sender: XMPPStream!) {        print("ok")        do {            try sender.authenticate(withPassword: 密码)        } catch let error {            print(error)        }    }    /// 用户登陆成功    func xmppStreamDidAuthenticate(_ sender: XMPPStream!) {        print("登陆成功")        let presence = XMPPPresence(type: "available")        xmppStream.send(presence)    }    /// 退出登陆的回调    func xmppStreamDidDisconnect(_ sender: XMPPStream!, withError error: Error!) {        print("退出成功")    }    /// 成功接收消息    func xmppStream(_ sender: XMPPStream!, didReceive message: XMPPMessage!) {        let text = message.body()        if text != nil {            label.text = text        }    }    /// 成功发送消息    func xmppStream(_ sender: XMPPStream!, didSend message: XMPPMessage!) {        print("成功发送消息 \(message.body())")    }}
你可能感兴趣的文章
[NLP] MXnet与TensorFlow的自然语言处理应用
查看>>
#####@@@#好好好好#####最全知识图谱介绍:关键技术、开放数据集、应用案例汇总
查看>>
MxNet使用总览
查看>>
DL4NLP —— seq2seq+attention机制的应用:文档自动摘要(Automatic Text Summarization)
查看>>
QA问答系统中的深度学习技术实现
查看>>
NLP专题论文解读:从Chatbot、NER到QA系统...
查看>>
端到端的TTS深度学习模型tacotron(中文语音合成)
查看>>
神经网络在关系抽取中的应用
查看>>
大规模知识图谱的构建、推理及应用
查看>>
揭秘 DeepMind 的关系推理网络
查看>>
概率图模型(PGM)模式推断与概率图流
查看>>
MySQL中REGEXP正则表达式使用大全
查看>>
ArangoDB、Neo4j、OrientDB单机性能比较
查看>>
MFCC(Mel 倒谱系数)
查看>>
python2代码批量转为python3代码
查看>>
贝叶斯优化: 一种更好的超参数调优方式
查看>>
Tensorflow 多任务学习 概念介绍
查看>>
Keras 多任务实现,Multi Loss #########Keras Xception Multi loss 细粒度图像分类
查看>>
#####好好好####从Google Visor到Microsoft NNI再到Advisor调参服务接口发展史
查看>>
tensorflow中的共享变量(sharing variables) 最佳方式variable_scope()命名空间来完成
查看>>