初始化流转图
代码
代码语言: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)
}