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

2019-10-22 14:25:42 浏览数 (1)

初始化流转图

代码

代码语言: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)
}

0 人点赞