0
votes

I am building a chat client for iOS using ejabberd and Swift. When I try to retrieve the roster for a user it returns an empty set despite this user having many buddies. Where exactly am I going wrong? I have found similar questions but they seem dated.

Here is my code:

class XMPPController: NSObject {

var hostName: String
var hostPort: UInt16
var password: String
var userJID: XMPPJID
var xmppStream: XMPPStream
var xmppRoster: XMPPRoster!
var xmppRosterStorage: XMPPRosterCoreDataStorage!

init(inputHostName: String, inputUserJIDString: String, inputHostPort: UInt16, inputPassword: String) throws {
            
    
    guard let formattedUserJID = XMPPJID(string: inputUserJIDString) else {
        throw XMPPControllerError.wrongUserJID
    }
    
  

    
    self.hostName = inputHostName
    self.hostPort = inputHostPort
    self.password = inputPassword
    self.userJID = formattedUserJID
            
    self.xmppStream = XMPPStream()
    self.xmppStream.hostName = hostName
    self.xmppStream.hostPort = hostPort
    self.xmppStream.myJID = userJID
    self.xmppRosterStorage = XMPPRosterCoreDataStorage()
    self.xmppRoster = XMPPRoster(rosterStorage: xmppRosterStorage)

    

    super.init()
  
    xmppStream.addDelegate(self, delegateQueue: DispatchQueue.main)
    xmppRoster.addDelegate(self, delegateQueue: DispatchQueue.main)

    xmppRoster.autoFetchRoster = true;
    xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = true;
    xmppRoster.activate(xmppStream)

    print(xmppRosterStorage.jids(for: xmppStream))
    

}


func connect() {
    
    
    if self.xmppStream.isDisconnected {
        
    }
    
    do {
        try self.xmppStream.connect(withTimeout: 5)
        
        
    } catch {
        print("Error Connecting")
    }
    
}

func disconnect(){
    
    self.xmppStream.disconnect()
    
}

}

extension XMPPController: XMPPStreamDelegate {

func xmppStreamDidConnect(_ sender: XMPPStream) {
    print("Stream: Connected")
    try! sender.authenticate(withPassword: password)
    
    
}

func xmppStreamDidDisconnect(_ sender: XMPPStream, withError error: Error?) {
    print("Stream: Disconnected")
}

func xmppStreamDidAuthenticate(_ sender: XMPPStream) {
    let presence = XMPPPresence()
    self.xmppStream.send(presence)
    
    

    print("Stream: Authenticated")
    
    NotificationCenter.default.post(name: Notification.Name(rawValue: authenticatedNotificationKey), object: self)
    
}

func xmppStream(_ sender: XMPPStream, didNotAuthenticate error: DDXMLElement) {
    print("Wrong credentials")
}

}

Thank you.

2

2 Answers

0
votes

Answering my own questions.

Two problems.

  1. I did not define the superclass XMPPRosterDelegate for XMPPController.

  2. I did not call

    func xmppRosterDidEndPopulating(_ sender: XMPPRoster) {

     print(xmppRosterStorage.jids(for: xmppStream))
    

    }

something that could only be done having declared XMPPRosterDelegate.

0
votes

I cannot see to your add any user your roster. You can try this :

func sendSubscribePresenceFromUserRequest ( _ username : String) {
    let otherUser = XMPPJID(string: "\(username)@\(xmppDomain)")!
    self.roster.addUser(otherUser, withNickname: "Other user name" , groups: nil, subscribeToPresence: true)
}

Then You call setup XMPPRoster method after 'xmppStreamDidAuthenticate' method just like this :

func rosterSetup() {
    let storage = XMPPRosterCoreDataStorage.sharedInstance()
    roster = XMPPRoster(rosterStorage: storage!, dispatchQueue: DispatchQueue.main)
    if let rosterXmpp = roster {
        rosterXmpp.setNickname("Your name" , forUser: stream.myJID!)
        rosterXmpp.activate(stream)
        rosterXmpp.addDelegate(self, delegateQueue: DispatchQueue.main)
        rosterXmpp.autoFetchRoster = true
        rosterXmpp.autoClearAllUsersAndResources = true
        rosterXmpp.autoAcceptKnownPresenceSubscriptionRequests = true
        rosterXmpp.fetch()
    }
}