robbiehanson / XMPPFramework

An XMPP Framework in Objective-C for Mac and iOS
Other
5.91k stars 2.09k forks source link

Swift 3 implementation issue #817

Open Satheez opened 8 years ago

Satheez commented 8 years ago

Hi, i've implemented those functions. It's working on swift 2.3. But I'm having problem when using with swift 3. The issue is "xmppStream.myJID = XMPPJID.jidWithString(jabberID)". Xcode says that jidWithString is not a funtion anymore.

So could you please tell iss there any alternative to assign the jabberid?

Many thanks in advance.

horstleung commented 8 years ago

Xcode tell me to try XMPPJID(string: "") , not sure working or not. I am still migrating my project to Swift 3. (lots of errors, yea)

And I am facing the problem of ambiguous use of elementForName. Anyone fixed this problem with magic?

Satheez commented 8 years ago

hey thanks for responding..

actually I found a solution to implement xxmp with swift 3.

I'm using pod ->

pod 'XMPPFramework', :git => "https://github.com/robbiehanson/XMPPFramework.git", :branch => 'master'

And the connecting query follows > let xmppStream = XMPPStream() xmppStream?.myJID = XMPPJID.init(string: jabberID) // jabberID is your open fire username xmppStream?.hostName = "your_registered_domain" xmppStream?.hostPort = 5222 xmppStream?.enableBackgroundingOnSocket = true do { try xmppStream?.connect(withTimeout: XMPPStreamTimeoutNone)

            print("Connection success")
            return true
        } catch {
            print("Something went wrong!")
            return false

}

and you have to include all other functions like xmppStreamDidConnect, xmppStream etc

It works for me... :)

AbrahamSev commented 8 years ago

Hi there. Same problem here. I'm using swift3, but never connect to the server so i can't try to authenticate user. Never enters to xmppStreamDidConnect(), can you post your working code?

Thanks a lot

Satheez commented 8 years ago

Sure.. this is the app AppDelegate code. (Before everything you must setup your domain, username and password.


import UIKit import XMPPFramework import UserNotifications

protocol ChatDelegate { func buddyWentOnline(name: String) func buddyWentOffline(name: String) func didDisconnect() }

@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, XMPPRosterDelegate, XMPPStreamDelegate, UNUserNotificationCenterDelegate{

var window: UIWindow?
var delegate:ChatDelegate! = nil
let xmppStream = XMPPStream()
let xmppRosterStorage = XMPPRosterCoreDataStorage()
var xmppRoster: XMPPRoster

override init() {
    xmppRoster = XMPPRoster(rosterStorage: xmppRosterStorage)
}

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    registerForPushNotifications()
    UIApplication.shared.applicationIconBadgeNumber   = 0

    setupStream()
   _ = connect()

    is_app_active = true

    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 invalidate graphics rendering callbacks. Games should use this method to pause the game.

    disconnect()
}

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 active state; here you can undo many of the changes made on entering the background.

}

func applicationDidBecomeActive(_ application: UIApplication) {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

        _ = connect()

}

func applicationWillTerminate(_ application: UIApplication) {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.

        disconnect()

}

//MARK: Private Methods
private func setupStream() {
    //xmppRoster = XMPPRoster(rosterStorage: xmppRosterStorage)
    xmppRoster.activate(xmppStream)
    xmppStream?.addDelegate(self, delegateQueue: DispatchQueue.main)
    xmppRoster.addDelegate(self, delegateQueue: DispatchQueue.main)
}

private func goOnline() {
    let presence = XMPPPresence()
    //let domain = xmppStream.myJID.domain
    //print("XXXOX : \(xmppStream.myJID)")
    //if domain == "gmail.com" || domain == "gtalk.com" || domain == "talk.google.com" {
    //let priority = DDXMLElement.element(withName: "priority", stringValue: "24") as! DDXMLElement
    //presence?.addChild(priority)
    //}
    xmppStream?.send(presence)
    //print("XXOS : WENT ONLINE")
}

private func goOffline() {
    let presence = XMPPPresence(type: "unavailable")
    xmppStream?.send(presence)
}

func connect() -> Bool {
    print(xmppStream)
    if !(xmppStream?.isConnected())! {
        let jabberID = "your_jabberid"
        let myPassword = "password"

        if !(xmppStream?.isDisconnected())! {
            return true
        }
        if jabberID == nil && myPassword == nil {
            return false
        }

        xmppStream?.myJID = XMPPJID.init(string: jabberID)

        xmppStream?.hostName = "your domain name"
        xmppStream?.hostPort = 5222

        xmppStream?.enableBackgroundingOnSocket = true

        do {
            try xmppStream?.connect(withTimeout: XMPPStreamTimeoutNone)

            print("Connection success")
            return true
        } catch {
            print("Something went wrong!")
            return false
        }
    } else {
        return true
    }
}

func disconnect() {
    goOffline()
    xmppStream?.disconnect()
}

//MARK: XMPP Delegates
func xmppStreamDidConnect(_ sender: XMPPStream!) {
    do {
        try xmppStream?.authenticate(withPassword: "password")
    }catch let error as NSError {
        print("Could not authonticate")
        print("OSS : error \(error)")
    }
}

func xmppStreamDidAuthenticate(_ sender: XMPPStream!) {
    goOnline()
}

func xmppStream(_ sender: XMPPStream!, didReceive iq: XMPPIQ!) -> Bool {
    //print("Did receive IQ")
    return false
}

func xmppStream(_ sender: XMPPStream!, didReceive message: XMPPMessage!) {

     print("Did received message \(message)")
}

private func xmppStream(sender: XMPPStream!, didSendMessage message: XMPPMessage!) {
    print("Did send message \(message)")
}

func xmppStream(_ sender: XMPPStream!, didReceive presence: XMPPPresence!) {

// let presenceType = presence.type() // let myUsername = sender.myJID.user // let presenceFromUser = presence.from().user // //print("YYO : (myUsername)") // if presenceFromUser != myUsername { // print("Did receive presence from (presenceFromUser)") // if presenceType == "available" { // delegate.buddyWentOnline(name: "(presenceFromUser)@openstm") // } else if presenceType == "unavailable" { // delegate.buddyWentOffline(name: "(presenceFromUser)@openstm") // } // } }

func xmppRoster(_ sender: XMPPRoster!, didReceiveRosterItem item: DDXMLElement!) {

    print("Did receive Roster item")

} 

}


AbrahamSev commented 8 years ago

Thank you very much. I will try again to connect :)

Satheez commented 8 years ago

No problem,

Dont forget to call connect in the Controller

let appDelegate = UIApplication.shared.delegate as! AppDelegate // go online _ = appDelegate.connect()

All the best. 👍

pmehul55 commented 7 years ago

Not able send messages

here it is my code to get online users

func xmppStream(_ sender: XMPPStream!, didReceive presence: XMPPPresence!) {
    let presenceType = presence.type()
    let status = presence.status()
    let myUsername = sender.myJID.user
    let presenceFromUser = presence.from().user as String

    if presenceFromUser != myUsername {
        print("Did receive presence from \(presenceFromUser)")
        print("Type \(presenceType)")
        print("Type \(status)")

            if presenceType == "subscribe" {
            delegate.buddyWentOnline(name: "\(presenceFromUser)@domainName")
        } else if presenceType == "unavailable" {
            delegate.buddyWentOffline(name: "\(presenceFromUser)@domainName")
        }
    }
}

and this way i am sending message

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let alertController = UIAlertController(title: "Warning!", message: "It will send Yo! to the recipient, continue ?", preferredStyle: UIAlertControllerStyle.alert)
    alertController.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: { (action) -> Void in
        alertController.dismiss(animated: true, completion: nil)
    }))

    alertController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: { (action) -> Void in
        let message = "Yo!"
        let senderJID = XMPPJID.init(string: self.onlineBuddies[indexPath.row] as! String)
        let msg = XMPPMessage(type: "chat", to: senderJID)

        print("Sender JID %@",senderJID as Any)

        msg?.addBody(message)

        self.appDelegate.xmppStream?.send(msg)
    }))
    present(alertController, animated: true, completion: nil)
}

Please help me out, thanks in advance

MadBurea commented 7 years ago

hii not able to send message

As i can receive message and even know roaster availability and type whether composing or paused.

for send i have used this code let message = messageTextField.text

    var clientJid: XMPPJID!
    clientJid = XMPPJID.init(string: "Mad@700.305.150.890")
    let senderJID = clientJid
    let msg = XMPPMessage(type: "chat", to: senderJID)
    msg?.addBody(message)
    stream?.send(msg)

Here stream is XMPPStream

Please help

MadBurea commented 7 years ago

hii @pmehul55 Did you solved error. Have your message sent. if Yes then Plese help me

AbrahamSev commented 7 years ago

Hi. I already have working XMPP client, hope it helps

func sendXmppMessage(msg: String, to: String) { let toJID = to + "@" + xmpp_serverName // your server name let senderJID = XMPPJID.init(string: toJID) let xmppMsg = XMPPMessage(type: "chat", to: senderJID) xmppMsg?.addBody(msg) if xmppStream!.isAuthenticated() { xmppStream?.send(xmppMsg) }else{ msgStack.append(xmppMsg!) // Save your message for later XmppConnect() } }

This function must be coded in AppDelegate, but if you want to send xmppMessage from viewController you need to make an instance of appDelegate in your view controller first

in your view controller: let delegate = UIApplication.shared.delegate as! AppDelegate

after you instantiate your app delegate in your viewController, you can call the sendXmppMessage function:

delegate.sendXmppMessage(msg: "your message", to: "destinationBareJID")

pmehul55: And for the Roster, you should use 'available' instead of 'suscribe' to get buddies status.

ChanchalW commented 7 years ago

Hello , i am facing same issue my xmppStreamWillConnect(_ sender: XMPPStream!) is called but xmppStreamDidConnect(sender: XMPPStream!) is never called. Connection is not established ever.

Any one help on this?

chrisballinger commented 7 years ago

try xmppStreamDidConnect(_ sender: XMPPStream!)

On Mon, Mar 6, 2017 at 1:30 AM, ChanchalW notifications@github.com wrote:

Hello , i am facing same issue my xmppStreamWillConnect(_ sender: XMPPStream!) is called but xmppStreamDidConnect(sender: XMPPStream!) is never called. Connection is not established ever.

Any one help on this?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/robbiehanson/XMPPFramework/issues/817#issuecomment-284345181, or mute the thread https://github.com/notifications/unsubscribe-auth/AAfqHya_o7_0HZzS8r1mr9iS-keFHJvcks5ri9I4gaJpZM4Ka2Ry .

pmehul55 commented 7 years ago

Hello Chris Ballinger,

Hope you are doing well,

Please try below code for sending message.

        let completeMessage = DDXMLElement.element(withName: "message")

as! DDXMLElement

        completeMessage.addAttribute(withName: "id", stringValue:

messageID!)

        // Group Chat Message//

         if rosterInfo.roster_type == 1 {

            completeMessage.addAttribute(withName: "type", stringValue:

"groupchat")

            let requestElement = DDXMLElement.element(withName:

"request", uri: "urn:xmpp:receipts") as! DDXMLElement

            completeMessage.addChild(requestElement)

        }else

     // One to One Chat//

        {

            completeMessage.addAttribute(withName: "type", stringValue:

"chat")

        }

          completeMessage.addAttribute(withName: "to", stringValue:

senderJID)

         let body = DDXMLElement.element(withName: "body") as!

DDXMLElement

        body.stringValue = trimmedMessage

        completeMessage.addChild(body)

        sender.send(completeMessage)

On Tue, Mar 7, 2017 at 1:26 AM, Chris Ballinger notifications@github.com wrote:

try xmppStreamDidConnect(_ sender: XMPPStream!)

On Mon, Mar 6, 2017 at 1:30 AM, ChanchalW notifications@github.com wrote:

Hello , i am facing same issue my xmppStreamWillConnect(_ sender: XMPPStream!) is called but xmppStreamDidConnect(sender: XMPPStream!) is never called. Connection is not established ever.

Any one help on this?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/robbiehanson/XMPPFramework/issues/817#issuecomment- 284345181, or mute the thread https://github.com/notifications/unsubscribe- auth/AAfqHya_o7_0HZzS8r1mr9iS-keFHJvcks5ri9I4gaJpZM4Ka2Ry .

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/robbiehanson/XMPPFramework/issues/817#issuecomment-284512988, or mute the thread https://github.com/notifications/unsubscribe-auth/AHlBcV_zQz8xbNkBdZ9Q-AUlyNN3_z6vks5rjGTwgaJpZM4Ka2Ry .

ChanchalW commented 7 years ago

Hi @chrisballinger Thanks for reply. I accidentally found that error in my code. I have to _ before sender otherwise this method will not be called. And now my chatting is working fine.

dimsancing2015 commented 7 years ago

func xmppStream(_ sender: XMPPStream!, didReceive message: XMPPMessage!) { debugPrint(message.elements(forName: "about")) }

<message xmlns="jabber:client" from="pubsub.mynet.com" to="002225743@mynet.com" type="headline">
    <event xmlns="http://jabber.org/protocol/pubsub#event">
        <items type="headline" node="mynet.global">
            <item id="1495526003">
                <xml>
                    <title>My Net</title>
                    <about>Good for you!</about>
                    <published>2017-05-23 14:23:23</published>
                </xml>
            </item>
        </items>
    </event>
    <delay xmlns="urn:xmpp:delay" from="admin@mynet.com/jaxl#5022c770097cfbce285d9564a960f9c7" stamp="2017-05-23T07:53:23Z"/>
</message>)

I want to fetch element node (<about>) in message.

ChanchalW commented 7 years ago

Why don't you use xml parser. It will be more easy with parser rather then parsing node by node.