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 服务器之间的比较