用swift代码去调试SwiftXMPP:
输入了正确的用户名和密码,但是最后代码没有其他反应。
感觉像是:
没有执行对应的didReceivePresence和 didReceiveMessage
好像是:
感觉是:
xmppStreamDidAuthenticate
没有被调用到
-》所以也没用调用到goOnline
后来把:
curXmppStream!.hostName = "localhost"
改为:
print("server=\(server)") //Optional("192.168.1.110") if server != nil{ loginServer = server! } // curXmppStream!.hostName = "localhost" curXmppStream!.hostName = server!
然后可以执行到:
func xmppStreamDidConnect(sender: XMPPStream) { print("xmppStreamDidConnect") isOpen = true var error: NSError? do{ try curXmppStream!.authenticateWithPassword(password) print("authentification successful") }catch{ print("authentification error=\(error)") } }
但是没有执行到:
func xmppStreamDidAuthenticate(sender: XMPPStream) { print("didAuthenticate") goOnline() }
搜:
xmpp xmppStreamDidAuthenticate not called
参考:
iphone – XMPP authentication returns yes but XMPPStreamDidAuthenticate never called – Stack Overflow
再次尝试登陆:
do{ try curXmppStream!.authenticateWithPassword(password) print("authentification successful") //second try do{ try curXmppStream!.authenticateWithPassword(password) print("authentification successful") //second try }catch let error{ print("authentification error=\(error)") } }catch let error{ print("authentification error=\(error)") }
结果出错:
authentification error=Error Domain=XMPPStreamErrorDomain Code=1 "Please wait until the stream is connected." UserInfo={NSLocalizedDescription=Please wait until the stream is connected.}
找到代理函数定义了:
/** * This method is called after the XML stream has been fully opened. * More precisely, this method is called after an opening <xml/> and <stream:stream/> tag have been sent and received, * and after the stream features have been received, and any required features have been fullfilled. * At this point it's safe to begin communication with the server. **/ - (void)xmppStreamDidConnect:(XMPPStream *)sender; /** * This method is called after registration of a new user has successfully finished. * If registration fails for some reason, the xmppStream:didNotRegister: method will be called instead. **/ - (void)xmppStreamDidRegister:(XMPPStream *)sender; /** * This method is called if registration fails. **/ - (void)xmppStream:(XMPPStream *)sender didNotRegister:(NSXMLElement *)error; /** * This method is called after authentication has successfully finished. * If authentication fails for some reason, the xmppStream:didNotAuthenticate: method will be called instead. **/ - (void)xmppStreamDidAuthenticate:(XMPPStream *)sender;
现在出现另外的问题:
xmppStreamDidConnect被调用了两次
到此第二次调用时出现上面的错误:UserInfo={NSLocalizedDescription=Please wait until the stream is connected.}
搜:
xmpp xmppStreamDidConnect called twice
参考:
搜:
swift xmppStreamDidAuthenticate
后来参考:
添加didNotAuthenticate:
// //func xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error; // @objc func xmppStream(sender: XMPPStream?, didNotAuthenticate: NSXMLElement?) { // // } func xmppStream(sender: XMPPStream!, didNotAuthenticate error: DDXMLElement!) { print("didNotAuthenticate") print("error=\(error)") //error=<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure> }
此处:
服务器已经挂了
然后对于authenticateWithPassword,也还是返回true的。。。
然后此处didNotAuthenticate会返回:
<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>
然后等openfire服务器正常后,还是上述错误。
添加了端口:
curXmppStream?.hostPort = 7070
后,didNotAuthenticate没有再被执行到。
但是其他的
xmppStreamDidAuthenticate
以及:
didReceiveMessage
didReceivePresence
也都没有被执行到。。。
参考:
难道是:
密码加密了?
导致认证,登陆不成功?
但是却也不执行didNotAuthenticate啊。。
参考:
去折腾:
然后继续调试。
然后用代码:
// // AppDelegate.swift // SwiftXMPP // // Created by Felix Grabowski on 10/06/14. // Copyright (c) 2014 Felix Grabowski. All rights reserved. // import UIKit @available(iOS 8.0, *) @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, XMPPStreamDelegate { var window: UIWindow? var viewController: BuddyListViewController? var password: String = "" var isOpen: Bool = false var curXmppStream: XMPPStream? var chatDelegate: ChatDelegate? var messageDelegate: MessageDelegate? var loginServer: String = "" func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. return true } func applicationWillResignActive(application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } func applicationDidEnterBackground(application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(application: UIApplication) { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } func applicationDidBecomeActive(application: UIApplication) { print("applicationDidBecomeActive") self.connect() } func applicationWillTerminate(application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } func setupStream() { print("setupStream") curXmppStream = XMPPStream() curXmppStream!.addDelegate(self, delegateQueue: dispatch_get_main_queue()) } func connect() -> Bool { print("connecting") setupStream() //NSUserDefaults.standardUserDefaults().setValue("[email protected]", forKey: "userID") let b = NSUserDefaults.standardUserDefaults().stringForKey("userID") print("user defaults: " + "\(b)") //Optional("[email protected]") let jabberID: String? = NSUserDefaults.standardUserDefaults().stringForKey("userID") print("jabberID=\(jabberID)") //Optional("[email protected]") let myPassword: String? = NSUserDefaults.standardUserDefaults().stringForKey("userPassword") print("myPassword=\(myPassword)") //Optional("password1") let server: String? = NSUserDefaults.standardUserDefaults().stringForKey("loginServer") print("server=\(server)") //Optional("192.168.1.110") if server != nil{ loginServer = server! } // curXmppStream!.hostName = "localhost" curXmppStream!.hostName = server! // curXmppStream?.myJID.domain = "localhost" //curXmppStream!.hostPort = 5222 //curXmppStream!.hostPort = 7070 print("curXmppStream=\(curXmppStream)") //Optional(<XMPPStream: 0x7fd0f8feb950>) if let stream = curXmppStream { if !stream.isDisconnected() { return true } if jabberID == nil || myPassword == nil{ print("no jabberID set:" + "\(jabberID)") print("no password set:" + "\(myPassword)") return false } stream.myJID = XMPPJID.jidWithString(jabberID) password = myPassword! do{ try stream.connectWithTimeout(XMPPStreamTimeoutNone) }catch let error{ let alert = UIAlertController(title: "Alert", message: "Cannot connect to : \(error)", preferredStyle: UIAlertControllerStyle.Alert) alert.addAction(UIAlertAction(title: "Click", style: UIAlertActionStyle.Default, handler: nil)) self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil) return false } } return true } func disconnect() { goOffline() curXmppStream!.disconnect() print("disconnecting") } func goOffline() { print("goOffline") let presence = XMPPPresence(type: "unavailable") curXmppStream!.sendElement(presence) } func goOnline() { let presence = XMPPPresence() // let presence = XMPPPresence(type: "away") curXmppStream!.sendElement(presence) } func xmppStreamDidConnect(sender: XMPPStream) { print("xmppStreamDidConnect") isOpen = true do{ try curXmppStream!.authenticateWithPassword(password) print("authentification successful") }catch let error{ print("authentification error=\(error)") } } func xmppStreamDidAuthenticate(sender: XMPPStream) { print("didAuthenticate") print("sender.isAuthenticated()=\(sender.isAuthenticated())") //true print("sender.myJID=\(sender.myJID)") //[email protected]/8f0a93af print("sender.myJID.domain=\(sender.myJID.domain)") //192.168.1.110 print("sender.myJID.domainJID()=\(sender.myJID.domainJID())") //192.168.1.110 goOnline() } func xmppStream(sender: XMPPStream!, didNotAuthenticate error: DDXMLElement!) { print("didNotAuthenticate") print("error=\(error)") //error=<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure> print("sender.myJID=\(sender.myJID)") //[email protected] print("sender.myJID.domain=\(sender.myJID.domain)") //192.168.1.110 print("sender.myJID.domainJID()=\(sender.myJID.domainJID())") //192.168.1.110 } //when receive add friend request func xmppStream(sender: XMPPStream!, didReceivePresenceSubscriptionRequest presence: XMPPPresence!) { print("didReceivePresenceSubscriptionRequest") print("sender=\(sender), presence=\(presence)") } //when send new message to friend func xmppStream(sender: XMPPStream!, didSendMessage message: XMPPMessage!) { print("Did send message \(message)") } //when receive new message from friend func xmppStream(sender: XMPPStream?, didReceiveMessage: XMPPMessage?) { if let message:XMPPMessage = didReceiveMessage { print("message: \(message)") if let msg: String = message.elementForName("body")?.stringValue() { if let from: String = message.attributeForName("from")?.stringValue() { let m: NSMutableDictionary = [:] m["msg"] = msg m["sender"] = from print("messageReceived") if messageDelegate != nil { messageDelegate!.newMessageReceived(m) } } } else { return } } } //when receive friend become online func xmppStream(sender: XMPPStream?, didReceivePresence: XMPPPresence?) { print("didReceivePresence") if let presence = didReceivePresence { let presenceType = presence.type() let myUsername = sender?.myJID.user let presenceFromUser = presence.from().user print(chatDelegate) if chatDelegate != nil { if presenceFromUser != myUsername { if presenceType == "available" { chatDelegate?.newBuddyOnLine("\(presenceFromUser)" + "@" + "\(loginServer)") } else if presenceType == "unavailable" { chatDelegate?.buddyWentOffline("\(presenceFromUser)" + "@" + "\(loginServer)") } } } print(presenceType) } } // func xmppRoster(sender: XMPPRoster!, didReceiveRosterItem item: DDXMLElement!) { // print("Did receive Roster item") // } }
正常执行后,代码中也执行到了:
didReceivePresence
Mac下的Aduim中,可以获得用户上线通知了:
点击通知可以进入聊天窗口:
然后停止调试代码,则Adium中也可以检测到用户下线了:
然后经过调试,终于可以显示出buddy用户列表了:
然后对于SwiftXMPP的demo的代码经过一定修改:
主要是:
ChatViewController.swift
中的cellForRowAtIndexPath:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ print("ChatViewController cellForRowAtIndexPath") let s = messages.objectAtIndex(indexPath.row) as! NSDictionary let cellIdentifier = "MessageCellIdentifier" var cell:UITableViewCell? = tableView.dequeueReusableCellWithIdentifier(cellIdentifier)! as UITableViewCell if !(cell != nil) { cell = UITableViewCell(style: .Value1, reuseIdentifier: cellIdentifier) } if let c = cell { // println(s) c.textLabel!.text = s["msg"] as? String c.detailTextLabel!.text = s["sender"] as? String c.accessoryType = .None c.userInteractionEnabled = false } return cell! }
中的:
MessageCellIdentifier
和
c.detailTextLabel!.text
实际上此处的Storyboard中是没有对应的cell的,所以去添加上:
找到:
Main.Storyboard中的Chat View Controller中的TView,然后在其中,
参考上面的Buddy的List View的也有个UserCellIdentifier
去给Chat也加一个TableViewCell,从右下角的地方拖动过来一个,放到TView的下面子节点
然后再去设置:
Identified设置为,代码中的,MessageCellIdentifier-》代码中才能用tableView.dequeueReusableCellWithIdentifier(“MessageCellIdentifier”)
Style设置为Subtitle-》这样代码cell中才有detailText可用。
最后调试使得部分的逻辑跑通了:
即:
从别的客户端,比如Mac的Aduim中发送消息,iOS模拟器中,即代码中,是可以收到消息的
但是:从(iOS模拟器中点击发送内容)代码中发送数据,到对应用户,在其他客户端中,却没有收到消息。。
但是也还是先把现在,部分可用的项目,打包,留存与此:
https://github.com/crifan/SwiftXMPP_Crifan/blob/master/SwiftXMPP_CrifanLi_20151126_receiveMsgOk.zip
然后好再去解决:
转载请注明:在路上 » [已解决]SwiftXMPP调试:没有执行到didReceivePresence和didReceiveMessage