前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS XMPP系列教程(Swift)三 代码实战

iOS XMPP系列教程(Swift)三 代码实战

作者头像
码客说
发布2019-10-22 14:25:42
4870
发布2019-10-22 14:25:42
举报
文章被收录于专栏:码客码客

初始化流转图

代码

代码语言:javascript
复制
class AppDelegate: UIResponder, UIApplicationDelegate ,XMPPStreamDelegate,XMPPRosterDelegate{
    var log = XCGLogger.defaultInstance();
    var window: UIWindow?
    var isImConnect: Bool = false;
    var isImLogin: Bool = false;
    var xmppStream: XMPPStream?;
    var xmppRoster:XMPPRoster?;
    var chatDelegate: ChatDelegate?;
    var messageDelegate: MessageDelegate?;
    var appMessageDelegate: MessageDelegate?;
    var jid:String?;
        ///入口
    func connect() -> Bool {
        log.info("连接IM服务器")
        setupStream();
        let defaults = NSUserDefaults.standardUserDefaults();
        LoadData.imServer = ZJ_PlistUtils.getProgramPlistStringValue("Config", keyName: "IMServer");
        if let imUserName = defaults.stringForKey(ProjectUserDefaults.ImUserName.rawValue){
            LoadData.imUserName = imUserName;
        }
        
        if let imUserPwd = defaults.stringForKey(ProjectUserDefaults.ImUserPwd.rawValue){
            LoadData.imUserPwd = imUserPwd;
        }
        
        if let imUserNick = defaults.stringForKey(ProjectUserDefaults.ImUserNick.rawValue){
            LoadData.imUserNick = imUserNick;
        }
        
        if let imUserPic = defaults.stringForKey(ProjectUserDefaults.ImUserPic.rawValue){
            LoadData.imUserPic = imUserPic;
        }
        
        if let imUserEmail = defaults.stringForKey(ProjectUserDefaults.ImUserEmail.rawValue){
            LoadData.imUserEmail = imUserEmail;
        }
        
        jid="\(LoadData.imUserName)@\(LoadData.imServer)"
        
        if let stream = xmppStream {
            if(stream.isConnected()){
                stream.disconnect();
            }
            xmppStream!.myJID =  XMPPJID.jidWithUser(LoadData.imUserName, domain: LoadData.imServer, resource: nil)
            xmppStream!.hostName=LoadData.imServer;
            xmppStream!.hostPort=5222;
            xmppStream?.enableBackgroundingOnSocket=true
            
            do {
                try xmppStream!.connectWithTimeout(10)
                return true
            } catch{
                return false;
            };
        }else{
            return false
        }
    }
    
    ///设置IM Stream对象
    func setupStream () {
        if(xmppStream == nil){
            xmppStream = XMPPStream();
            xmppStream!.addDelegate(self, delegateQueue: dispatch_get_main_queue());
            
            let xmppRosterDataStorage = XMPPRosterCoreDataStorage();
            xmppRoster = XMPPRoster(rosterStorage: xmppRosterDataStorage);
            xmppRoster?.activate(xmppStream);
            xmppRoster?.addDelegate(self, delegateQueue: dispatch_get_main_queue());
            
            //断线重连
            let xmppReconnect = XMPPReconnect();
            xmppReconnect.activate(xmppStream);
            xmppReconnect.addDelegate(self, delegateQueue: dispatch_get_main_queue());
        }
    }
    
    ///发送离线
    func goOffline() {
        let presence = XMPPPresence(type: "unavailable")
        xmppStream!.sendElement(presence)
    }
    
    ///发送在线
    func goOnline() {
        log.info("发送在线状态")
        let presence = XMPPPresence(type: "available")
        xmppStream!.sendElement(presence)
    }
    
    /**
     断开连接
     */
    func disconnect() {
        log.info("断开连接")
        goOffline()
        xmppStream!.disconnect()
    }
    
    //登录
    func login(){
        do {
            log.info("服务器:\(self.xmppStream?.hostName)")
            log.info("端口:\(self.xmppStream?.hostPort)")
            log.info("账号:\(self.xmppStream?.myJID.description)")
            log.info("密码:\(LoadData.imUserPwd)")
            try xmppStream!.authenticateWithPassword(LoadData.imUserPwd )
        } catch{
            print(error)
        };
    }
    
    //注册
    func register(){
        log.info("注册IM用户");
        let arr = NSMutableArray();
        arr.addObject(XMPPElement.elementWithName("username", stringValue: LoadData.imUserName));
        arr.addObject(XMPPElement.elementWithName("password", stringValue: LoadData.imUserPwd));
        arr.addObject(XMPPElement.elementWithName("name", stringValue: LoadData.imUserNick));
        arr.addObject(XMPPElement.elementWithName("email", stringValue: LoadData.imUserEmail));
        do {
            try xmppStream?.registerWithElements(arr as [AnyObject])
        } catch{
            print(error)
        };

    }
    //发送好友列表请求
    func queryRoster()->Void{
        log.info("发送好友请求")
        let type = "get"
        let iq = XMPPIQ()
        
        iq.addAttributeWithName("type", stringValue: type )
        let child=DDXMLNode.elementWithName("query") as! DDXMLNode
        child.setValue("jabber:iq:roster", forKey: "xmlns")
        iq.addChild(child)
        xmppStream?.sendElement(iq)
    }
    
    ///发送信息
    func sendMsg(sendMsg:SendMsg)->Void{
        log.info("发消息")
        
        let msg=XMPPMessage();
        msg.addAttributeWithName("type", stringValue: "chat");
        msg.addAttributeWithName("to", stringValue: "\(sendMsg.receiverName)@\(LoadData.imServer)");
        msg.addAttributeWithName("senderId", stringValue: sendMsg.senderId);
        msg.addAttributeWithName("senderName", stringValue: sendMsg.senderName);
        msg.addAttributeWithName("senderNickname", stringValue: sendMsg.senderNickname);
        msg.addAttributeWithName("senderPic", stringValue: sendMsg.senderPic);
        msg.addAttributeWithName("receiverId", stringValue: sendMsg.receiverId);
        msg.addAttributeWithName("receiverName", stringValue: sendMsg.receiverName);
        msg.addAttributeWithName("receiverNickname", stringValue: sendMsg.receiverNickname);
        msg.addAttributeWithName("receiverPic", stringValue: sendMsg.receiverPic);
        msg.addAttributeWithName("msgtype", stringValue: sendMsg.msgtype);
        msg.addAttributeWithName("voiceDuration", stringValue: sendMsg.voiceDuration);
        msg.addBody(sendMsg.msgbody);
        xmppStream?.sendElement(msg)
    }
    
    //添加好友
    func addFriend(name:String,nickName:String,xmppRoster:XMPPRoster){
        let jid=XMPPJID.jidWithUser(name, domain: LoadData.imServer, resource: nil);
        xmppRoster.addUser(jid, withNickname: nickName);
    }
    
    
    //-----------------------------------------华丽的分割线 XMPP的代理方法-------------------------------------------//
    //连接成功调用
    func xmppStreamDidConnect(_ sender: XMPPStream) {
        logger.info("连接IM服务器成功,开始登录")
        isImConnect = true;
        //进行登录
        login();
    }
    
    //注册成功后调用
    func xmppStreamDidRegister(_ sender: XMPPStream!) {
        logger.info("注册成功,开始登录")
        login();
    }
    
    func xmppStream(_ sender: XMPPStream!, didNotRegister error: DDXMLElement!) {
        logger.info("注册失败,停止操作");
    }
    
    //连接超时后调用
    func xmppStreamConnectDidTimeout(_ sender: XMPPStream!) {
        logger.info("连接IM服务器超时")
    }
    
    //登录失败调用
    func xmppStream(_ sender: XMPPStream!, didNotAuthenticate error: DDXMLElement!) {
        logger.info("登录失败,注册账号");
        register();
    }
    
    //登录成功调用
    func xmppStreamDidAuthenticate(_ sender: XMPPStream) {
        logger.info("登录成功,发送在线状态");
        isImLogin = true;
        //发送在线
        goOnline();
    }
    
    // 发送信息时调用
    func xmppStream(_ sender: XMPPStream!, didSend message: XMPPMessage!) {
        logger.info("发送Message");
    }
    
    //接收信息后调用
    func xmppStream(_ sender: XMPPStream?, didReceive didReceiveMessage: XMPPMessage?) {
        if let message:XMPPMessage = didReceiveMessage {
            let msgbody = ZJ_Xmpp.stringValue(message.forName("body"));
            let senderId = ZJ_Xmpp.stringValue(message.attribute(forName: "senderId"));
            let senderName = ZJ_Xmpp.stringValue(message.attribute(forName: "senderName"));
            let senderNickname = ZJ_Xmpp.stringValue(message.attribute(forName: "senderNickname"));
            let senderPic = ZJ_Xmpp.stringValue(message.attribute(forName: "senderPic"));
            let receiverId = ZJ_Xmpp.stringValue(message.attribute(forName: "receiverId"));
            let receiverName = ZJ_Xmpp.stringValue(message.attribute(forName: "receiverName"));
            let receiverNickname = ZJ_Xmpp.stringValue(message.attribute(forName: "receiverNickname"));
            let receiverPic = ZJ_Xmpp.stringValue(message.attribute(forName: "receiverPic"));
            let msgtype = ZJ_Xmpp.stringValue(message.attribute(forName: "msgtype"));
            let voiceDuration = ZJ_Xmpp.stringValue(message.attribute(forName: "voiceDuration"));
            let sendMsg = SendMsg(senderId: senderId, senderPic: senderPic, senderName: senderName, senderNickname: senderNickname, receiverId: receiverId, receiverPic: receiverPic, receiverName: receiverName, receiverNickname: receiverNickname, msgtype: msgtype, msgbody: msgbody,voiceDuration:voiceDuration);

            logger.info(sendMsg.toString());

            //播放提示音
            AudioServicesPlaySystemSound(SystemSoundID(1312));
            ZJ_Func.async({
                SQLiteDB.sharedInstance.execute(sql: "insert into talkmessage(msgType,message,senderName,senderPic,read,sender,receiver,srdate,isReceive,voiceDuration) values(?,?,?,?,?,?,?,?,?,?)",
                    parameters: [
                        msgtype,
                        msgbody,
                        senderNickname,
                        senderPic,
                        0,
                        senderName,
                        receiverName,
                        Date(),
                        1,
                        voiceDuration
                    ]
                );
                let loginUserId = UserDefaults.standard.string(forKey: ProjectUserDefaults.UserId.rawValue)!;
                let id = SQLiteDB.sharedInstance.execute(sql: "insert into appmessage(userId,loginName,name,image,detail,time,type,msgType,loginUserId) values(?,?,?,?,?,?,?,?,?)",
                    parameters: [
                        senderId,
                        senderName,
                        senderNickname,
                        senderPic,
                        msgbody,
                        Date(),
                        "talk",
                        msgtype,
                        loginUserId
                    ]
                );
                sendMsg.id = "\(id)";
                
                }, callBack: {
                    self.messageDelegate?.newMessageReceived(sendMsg);
                    self.appMessageDelegate?.newMessageReceived(sendMsg);
            });
        }
    }

    func xmppStream(_ sender: XMPPStream!, willSend iq: XMPPIQ!) -> XMPPIQ! {
        logger.info("发送IQ")
        return iq;
    }
    
    func xmppStream(_ sender: XMPPStream!, didReceive iq: XMPPIQ!) -> Bool {
        logger.info("接收IQ")
        return true
    }
    
    func xmppStream(_ sender: XMPPStream!, didSend presence: XMPPPresence!) {
        
    }
    
    func xmppStream(_ sender: XMPPStream?, didReceive didReceivePresence: XMPPPresence?) {
        logger.info("接收Presence");
        if let presence = didReceivePresence {
            let presenceType = presence.type()
            let myUsername = sender?.myJID.user
            let presenceFromUser = presence.from().user
            
            if presenceFromUser != myUsername {
                if presenceType == "available" {
                    logger.info("在线用户:\(presenceFromUser)");
                    if chatDelegate != nil {
                        chatDelegate?.newBuddyOnline("\(presenceFromUser)" + "@" + "\(LoadData.imServer)")
                    }
                } else if presenceType == "unavailable" {
                    logger.info("离线用户:\(presenceFromUser)");
                    if chatDelegate != nil {
                        chatDelegate?.buddyWentOffline("\(presenceFromUser)" + "@" + "\(LoadData.imServer)")
                    }
                }
            }
            
        }
    }
}

代码中用到的工具类

代码语言:javascript
复制
import Foundation
import XMPPFramework

class ZJ_Xmpp{
    static func stringValue(_ element:DDXMLElement?) -> String{
 
        if(element == nil){
            return "";
        }else{

            return element!.stringValue!;
        }
    }
    
    static func stringValue(_ node:DDXMLNode?) -> String{

        if(node == nil){
            return "";
        }else{
            
            return node!.stringValue!;
        }
    }
}

用户状态改变的代理(暂时没用)

代码语言:javascript
复制
import Foundation
protocol ChatDelegate{
    func newBuddyOnline(buddyName:String)
    func buddyWentOffline(buddyName:String)
    func didDisconnect()
}

接受消息的代理(通知消息列表页面刷新)

代码语言:javascript
复制
import Foundation
protocol MessageDelegate {
    func newMessageReceived(sendMsg: SendMsg)
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-03-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初始化流转图
  • 代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档