6. Swift 基于Xmpp和openfire实现一个简单的登录注册

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了6. Swift 基于Xmpp和openfire实现一个简单的登录注册相关的知识,希望对你有一定的参考价值。

1. 基本步骤:首先导入Xmpp框架,配置环境

    -》由于我们使用的是OC的Xmpp框架,再进行Swift开发时需要进行桥接。 具体方法就是创建一个基于c的.h的头文件,然后将我们需要编译OC的语言的头文件包含这个.h文件中;

   技术分享

技术分享

  -》然后导入如下库文件,在头头文件选择路径中 

 技术分享技术分享

 

  如上图, 设置header Search paths 设置头文件的搜索路径,导入libxml2库文件相对路径,***注意前面是 usr 。以前第一次装的时候写成user找了半个多小时 

  -> 然后创建界面,随便弄两个框框和按钮自定义一个建议的界面。

      应为在应用程序中用户名和密码可能被反复的使用,所以我们需要讲它门设置成一个单利类。 

     如下代码所示:

import UIKit

class WSBUserinfo: NSObject {

    // 登录的用户名密码

    var  userName : String?   

    var  userPasswd : String?

    // 注册的用户名密码

    var  userRegisterName : String?

    var  userRegisterPasswd : String?

    // 为了区分登录和注册 

    var  isLogin : Bool?

    // 单例

    class func getShareInstance() -> WSBUserinfo{

        struct Singleton {

            static var  dispatchOne : dispatch_once_t = 0

            static var  instance : WSBUserinfo? = nil

        }

        dispatch_once(&Singleton.dispatchOne) { () -> Void in

            Singleton.instance = WSBUserinfo()

        }

        return Singleton.instance!

    }

}

    //由于登录流程设计到了xmpp流协议实现,步骤较多。这里我们可以单独封装一个工具类。这样我们的登录和注册的主控制器就能得到极大的解脱:

     在登录控制器中我们只需要将输入框的用户输入信息赋值到单利用户信息类 UserInfo里

     然后调用 单利工具类的 usrLogin()方法及可自动完成所有的登录流程

     再通过指定一个协议,实现对登录和注册状态的监听;

     注册控制器的逻辑同上,这里就不重复了 。

    注意点1:再每次连接请求时先把之前的连接断开,这样能避免一个账号长连接而其它的账号无法连接。

    注意点2:再发送登录注册时中间都涉及到了共同的连接请求和连接状态请求,我们需要在单利类中建立一个Bool属性值做分支判定,这样我们只需要在方法内部做简单的调整,从而省去大量的代码步骤。 

    具体步骤请看下面代码

 

import UIKit

 

class WSBLoginViewController: UIViewController,WSBXMPPLoginDelegate {

    @IBOutlet weak var userNameField: UITextField!

 

    @IBOutlet weak var userPasswdField: UITextField!

    

    @IBAction func loginBtnClick(sender: AnyObject) {

        WSBUserinfo.getShareInstance().isLogin = true

        print("用户名:\(userNameField.text!)")

        print("密码是:\(userPasswdField.text!)")

        // 把用户名 密码存入工具类 WSBUserinfo 这个单例对象中

        WSBUserinfo.getShareInstance().userName = userNameField.text!

        WSBUserinfo.getShareInstance().userPasswd = userPasswdField.text!

        // 调用XMPP 工具类 完成登录

        // 登录之前先给WSBXMPPTool设置代理

        WSBXMPPTool.getSharedInstance().loginDelegate = self

        WSBXMPPTool.getSharedInstance().userLogin()

    }

    /** 登录协议中的方法 */

    func loginSuccess() {

        print("登录成功")

        // 切换到主界面

        let  storyBoard  = UIStoryboard.init(name: "Main", bundle: nil)

        UIApplication.sharedApplication().keyWindow?.rootViewController =

            storyBoard.instantiateInitialViewController()

    }

    func loginFailed() {

        print("登录失败")

    }

    func loginNetError() {

        print("登录时网络错误")

    }

    override func viewDidLoad() {

        super.viewDidLoad()

    }

    deinit{

        print("deinit\(self)")

    }

}

    

    RegisterViewController:

import UIKit

 

class WSBRegisterViewController: UIViewController,WSBXMPPRegisterDelegate {

    

    @IBOutlet weak var userRegiserName: UITextField!

 

    @IBOutlet weak var userRegisterPasswd: UITextField!

 

    @IBAction func registerBtnClick(sender: AnyObject) {

        // 说明这是注册行为

        WSBUserinfo.getShareInstance().isLogin = false

        WSBUserinfo.getShareInstance().userRegisterName = self.userRegiserName.text!

        WSBUserinfo.getShareInstance().userRegisterPasswd = self.userRegisterPasswd.text!

        // 调用XMPPTool的 注册方法

        WSBXMPPTool.getSharedInstance().registerDelegate = self

        WSBXMPPTool.getSharedInstance().userRegister()

        

    }

    /** 实现注册协议中的方法 */

    func registerSuccess() {

        print("注册成功")

        self.dismissViewControllerAnimated(true, completion: nil)

    }

    func registerFailed() {

        print("注册失败")

    }

    func registerNetError() {

        print("注册时网络错误")

    }

}

 

  登录和注册协议

import Foundation

// 登录协议 

protocol WSBXMPPLoginDelegate : NSObjectProtocol {

     // 登录成功

     func  loginSuccess()

     // 登录失败

     func  loginFailed()

    //  网络错误

     func  loginNetError()

}

// 注册协议

protocol WSBXMPPRegisterDelegate : NSObjectProtocol {

    // 注册成功

    func  registerSuccess()

    // 注册失败

    func  registerFailed()

    // 注册网络错误

    func  registerNetError()

}

Swift:

import UIKit

/** 桥接文件 项目--buildSettings --> 搜索 Objective-c Bride 设置即可

  这是一个XMPP的工具类 可以完成登录和注册的行

*/

class WSBXMPPTool: NSObject, XMPPStreamDelegate {

    var  xmppStream : XMPPStream!

    // 登录的Delegate

    weak var loginDelegate : WSBXMPPLoginDelegate?

    // 注册的Deletegate

    weak var registerDelegate : WSBXMPPRegisterDelegate?

    // 保证xmppStream 使用时非空

    override init() {

        super.init()

        setupXmppStream()

    }

    class func  getSharedInstance() -> WSBXMPPTool {

        struct Singleton {

            static var predicate : dispatch_once_t = 0

            static var instance : WSBXMPPTool? = nil

        }

        dispatch_once(&Singleton.predicate) { () -> Void in

            Singleton.instance = WSBXMPPTool()

        }

        return  Singleton.instance!

    }

    // 设置流 设置代理

    func setupXmppStream(){

        xmppStream = XMPPStream()

        xmppStream.addDelegate(self, delegateQueue: dispatch_get_main_queue())

    }

    // 连接服务器

    func connectToHost(){

        // 先断开上次的 不断开登录之后没法再登录

        xmppStream.disconnect();

        // 调用设置xmppStream 

        if self.xmppStream == nil {

           self.setupXmppStream()

        }

        var userName : String? = nil

        if WSBUserinfo.getShareInstance().isLogin! {

            userName = WSBUserinfo.getShareInstance().userName

        }else{

            userName = WSBUserinfo.getShareInstance().userRegisterName

        }

        // 构建jid   设置hostName 和 port 

        xmppStream.myJID = XMPPJID.jidWithUser(userName, domain: XMPPDOMAIN, resource: "iphone")

        xmppStream.hostName = XMPPHOSTNAME

        xmppStream.hostPort = XMPPPORT

        do {

            try xmppStream.connectWithTimeout(XMPPStreamTimeoutNone)

        }catch let error as NSError{

            print(error.description)

        }

    }

    // 连接成功(代理方法)

    func xmppStreamDidConnect(sender: XMPPStream!) {

        // 调用发送密码 请求授权

        if WSBUserinfo.getShareInstance().isLogin!{

            self.sendLoginPasswd()

        }else{

            // 使用密码注册

            self.sendRegisterPasswd()

        }

    }

    // 发送密码 注册

    func sendRegisterPasswd(){

        do{

            try xmppStream.registerWithPassword(WSBUserinfo.getShareInstance().userRegisterPasswd)

        }catch let error as NSError{

            print(error.description)

        }

    }

    // 发送密码 请求授权

    func sendLoginPasswd(){

        do{

         try xmppStream.authenticateWithPassword(WSBUserinfo.getShareInstance().userPasswd)

        }catch let error as NSError{

             print(error.description)

        }

    }

    // 授权成功(代理方法)

    func xmppStreamDidAuthenticate(sender: XMPPStream!) {

        print("授权成功")

        // 发送在线消息

        self.sendOnLine()

        // 调用代理的登录成功的方法

        loginDelegate?.loginSuccess()

    }

    // 发送在线消息

    func sendOnLine(){

      xmppStream.sendElement(XMPPPresence())

    }

    // 授权失败

    func xmppStream(sender: XMPPStream!, didNotAuthenticate error: DDXMLElement!) {

        print(error.description)

        // 授权失败 调用代理的登录失败的方法

        loginDelegate?.loginFailed()

    }

    // 连接断开(代理方法)

    func xmppStreamDidDisconnect(sender: XMPPStream!, withError error: NSError!) {

        // 如果网络有问题断开 则error 中有值

        // 如果是主动断开  则error是 nil

        if error != nil {

            if WSBUserinfo.getShareInstance().isLogin!{

              //登录网络有问题 调用代理的网络错误

            loginDelegate?.loginNetError()

            }else{

                // 注册时网络有问题

                registerDelegate?.registerNetError()

            }

        }

    }

    //注册成功 (代理方法 )

    func  xmppStreamDidRegister(sender: XMPPStream!) {

        // 调用代理的注册成功

        registerDelegate?.registerSuccess()

    }

    // 注册失败 (代理方法 )

    func xmppStream(sender: XMPPStream!, didNotRegister error: DDXMLElement!) {

        registerDelegate?.registerFailed()

    }

    // 用户完成登录的方法

    func  userLogin(){

        self.connectToHost()

    }

    // 用户完成注册的方法

    func  userRegister(){

        self.connectToHost()

    }

}

 

以上是关于6. Swift 基于Xmpp和openfire实现一个简单的登录注册的主要内容,如果未能解决你的问题,请参考以下文章

Android基于XMPP Smack及Openfire学习笔记

Tigase、Openfire 和任何其他开源 XMPP 服务器之间的比较

Android基于XMPP Smack Openfire下学习开发IM连接断开重连

XMPP - 第一讲 - 服务器Openfire

如何保证 XMPP 消息发送到 openfire 服务器?

Android基于xmpp的即时通讯应用