XMPPFramework Basic client relying using Cocoapods package.
-
Open Xcode and select Create a new project
![Xcode setup](https://github.com/processone/demo-xmpp-ios/blob/master/Setup%20resources/Capture%20d’écran%202015-07-22%20à%2011.15.32.png?raw=true =350x) -
Select Single View Application in the project editor
![Xcode setup](https://github.com/processone/demo-xmpp-ios/blob/master/Setup%20resources/Capture%20d’écran%202015-07-22%20à%2011.15.44.png?raw=true =350x) -
Fill all the required fields and then project location
![Xcode setup](https://github.com/processone/demo-xmpp-ios/blob/master/Setup%20resources/Swift_lang.png?raw=true =350x) -
Now quit Xcode, and open the terminal app
![Xcode setup](https://github.com/processone/demo-xmpp-ios/blob/master/Setup%20resources/Capture%20d’écran%202015-07-22%20à%2011.41.50.png?raw=true =350x) -
Navigate to your project directory and type
pod init
like so:
![Xcode setup](https://github.com/processone/demo-xmpp-ios/blob/master/Setup%20resources/Capture%20d’écran%202015-07-22%20à%2011.42.02.png?raw=true =350x) -
Edit the newly created Podfile by taping
emacs Podfile
(Feel free to use vim :)). It should look like this:
![Xcode setup](https://github.com/processone/demo-xmpp-ios/blob/master/Setup%20resources/Capture%20d’écran%202015-07-24%20à%2015.16.11.png?raw=true =350x)
Press ctrl+x, ctrl+s to save, then ctrl+x, ctrl+c to end editing -
Now Type
pod install
and wait for cocoapod to finish
![Xcode setup](https://github.com/processone/demo-xmpp-ios/blob/master/Setup%20resources/XMPPFramework_Swift_lang.png?raw=true =350x)
From now on you will have to open the xcworkspace file -
Open your
AppDelegate.h
and add the XMPP import:import XMPPFramework
-
Add the chat protocol at the top of your
AppDelegate
:protocol ChatDelegate { func buddyWentOnline(name: String) func buddyWentOffline(name: String) func didDisconnect() }
-
Add the following degegates:
XMPPRosterDelegate, XMPPStreamDelegate
-
Add XMPP properties:
var delegate:ChatDelegate! = nil let xmppStream = XMPPStream() let xmppRosterStorage = XMPPRosterCoreDataStorage() var xmppRoster: XMPPRoster override init() { xmppRoster = XMPPRoster(rosterStorage: xmppRosterStorage) }
-
Still in
AppDelegate
, add a new method calledsetupStream
, witch will be in charge of configuring the stream, roster and its storage:private func setupStream() { xmppRoster.activate(xmppStream) xmppStream.addDelegate(self, delegateQueue: dispatch_get_main_queue()) xmppRoster.addDelegate(self, delegateQueue: dispatch_get_main_queue()) }
And call it in
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
-
Implement the following methods:
private func goOnline() { let presence = XMPPPresence() let domain = xmppStream.myJID.domain if domain == "gmail.com" || domain == "gtalk.com" || domain == "talk.google.com" { let priority = DDXMLElement.elementWithName("priority", stringValue: "24") as! DDXMLElement presence.addChild(priority) } xmppStream.sendElement(presence) } private func goOffline() { let presence = XMPPPresence(type: "unavailable") xmppStream.sendElement(presence) } func connect() -> Bool { if !xmppStream.isConnected() { let jabberID = NSUserDefaults.standardUserDefaults().stringForKey("userID") let myPassword = NSUserDefaults.standardUserDefaults().stringForKey("userPassword") if !xmppStream.isDisconnected() { return true } if jabberID == nil && myPassword == nil { return false } xmppStream.myJID = XMPPJID.jidWithString(jabberID) do { try xmppStream.connectWithTimeout(XMPPStreamTimeoutNone) print("Connection success") return true } catch { print("Something went wrong!") return false } } else { return true } } func disconnect() { goOffline() xmppStream.disconnect() }
-
Call
connect()
infunc applicationDidBecomeActive(application: UIApplication)
anddisconnect()
infunc applicationWillResignActive(application: UIApplication)
-
Now the last but not the least, implement the xmpp delegates:
func xmppStreamDidConnect(sender: XMPPStream!) { do { try xmppStream.authenticateWithPassword(NSUserDefaults.standardUserDefaults().stringForKey("userPassword")) } catch { print("Could not authenticate") } } func xmppStreamDidAuthenticate(sender: XMPPStream!) { goOnline() } func xmppStream(sender: XMPPStream!, didReceiveIQ iq: XMPPIQ!) -> Bool { print("Did receive IQ") return false } func xmppStream(sender: XMPPStream!, didReceiveMessage message: XMPPMessage!) { print("Did receive message \(message)") } func xmppStream(sender: XMPPStream!, didSendMessage message: XMPPMessage!) { print("Did send message \(message)") } func xmppStream(sender: XMPPStream!, didReceivePresence presence: XMPPPresence!) { let presenceType = presence.type() let myUsername = sender.myJID.user let presenceFromUser = presence.from().user if presenceFromUser != myUsername { print("Did receive presence from \(presenceFromUser)") if presenceType == "available" { delegate.buddyWentOnline("\(presenceFromUser)@gmail.com") } else if presenceType == "unavailable" { delegate.buddyWentOffline("\(presenceFromUser)@gmail.com") } } } func xmppRoster(sender: XMPPRoster!, didReceiveRosterItem item: DDXMLElement!) { print("Did receive Roster item") }
-
Let's add a
LoginViewController
, you are free to add whatever you want in this ViewController, but yourlogin
method should look like this:@IBAction func login(sender: AnyObject) { NSUserDefaults.standardUserDefaults().setObject(loginTextField.text!, forKey: "userID") NSUserDefaults.standardUserDefaults().setObject(passwordTextField.text!, forKey: "userPassword") let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate if appDelegate.connect() { dismissViewControllerAnimated(true, completion: nil) } }
-
It's nice to be connected, but it'll be even better if we could get our buddies list. Create a
UITableViewController
subclass and addChatdelegate
and an ivarvar onlineBuddies = NSMutableArray()
to store the buddy list -
Now set yourself as delegate for chat, then init your array in viewDidLoad:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. appDelegate.delegate = self }
-
Then in your viewwillappear, check if you are connected like so:
override func viewDidAppear(animated: Bool) { if (NSUserDefaults.standardUserDefaults().objectForKey("userID") != nil) { if appDelegate.connect() { self.title = appDelegate.xmppStream.myJID.bare() appDelegate.xmppRoster.fetchRoster() } } else { performSegueWithIdentifier("Home.To.Login", sender: self) } }
-
After that implement the chat delegates methods:
func buddyWentOnline(name: String) { if !onlineBuddies.containsObject(name) { onlineBuddies.addObject(name) tableView.reloadData() } } func buddyWentOffline(name: String) { onlineBuddies.removeObject(name) tableView.reloadData() } func didDisconnect() { onlineBuddies.removeAllObjects() tableView.reloadData() }
-
The rest is pretty straightforward, you need to implement the
UITableView’s Delegates
:override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("CellIdentifier", forIndexPath: indexPath) cell.textLabel?.text = onlineBuddies[indexPath.row] as? String return cell } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return onlineBuddies.count } override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1 }
-
Now if you want to send a message when the user tap on a row, implement this method:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 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.dismissViewControllerAnimated(true, completion: nil) })) alertController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (action) -> Void in let message = "Yo!" let senderJID = XMPPJID.jidWithString(self.onlineBuddies[indexPath.row] as? String) let msg = XMPPMessage(type: "chat", to: senderJID) msg.addBody(message) self.appDelegate.xmppStream.sendElement(msg) })) presentViewController(alertController, animated: true, completion: nil) }
-
Build, run and start chatting with your friends !