iOS Chat App with XMPP framework
Nasir Ahmed Momin
Posted on December 21, 2019
Wants to build Chat App for iOS?
Lets gets started
XMPP stands for Xtensible Messaging & Presence Protocol.
Things required ?
- IM Server (I prefer MongooseIM)
- User (Account created)
You can download MongooseIM Package here & Install package
https://www.erlang-solutions.com/resources/download.html
Details for installation can be found here https://mongooseim.readthedocs.io/en/latest/user-guide/Getting-started/
On installation completes launch Terminal & execute following command
$ mongooseimctl start
then Check status
$ mongooseimctl status
When All thats done. You need a user, head down below & create user
$ mongooseimctl register <user> <host> <password>
Eg: $ mongooseimctl register user1 localhost qwerty
You can verify user creation $ mongooseimctl registered_users localhost
Till now server config & user creation completed.
Before jumping into code part, lets understand following things
- JID
- Stanza & its type.
-
Stream.
-
JID: is something by which each individual is uniquely identified is XMPP. It does looks like this
username@hostname/resource
username: is local part hostname: is domain part resource: is resource part which is optional in many cases - Stanza: is name of XML tag/piece that sends & received. Basic Stanza's are < message > < presence > & < iq >, details will be mentioned about them, if required in future
- Stream: is entry point for interprocess communication to start on shared file called Socket, which happens by < stream > tag.
-
JID: is something by which each individual is uniquely identified is XMPP. It does looks like this
We shall start working on iOS App.
I hope you guys knows how to create Xcode iOS Project & Pod setup.
In Podfile pod 'XMPPFramework'
then run pod install
Create XMPPController.swift file & make a singleton object.
class XMPPController: NSObject {
static let sharedInstance = XMPPController()
}
Now declare an XMPPStream instance & intilize it in init()
var stream: XMPPStream?
override init() {
self.stream = XMPPStream()
super.init()
}
Also declare following vars.
var hostName: String?
var userJID: XMPPJID?
var hostPort: UInt16?
var password: String?
Declare a connect function as below
func connect(withHostName name: String, userJID jid: String, hostPort port: UInt16, password pwd: String) {
guard let uJID = XMPPJID(string: jid) else {
return
}
hostName = name
userJID = uJID
hostPort = port
password = pwd
// Stream Configuration
stream?.hostName = name
stream?.myJID = uJID
stream?.hostPort = port
stream?.startTLSPolicy = .allowed
if stream!.isDisconnected {
do {
try stream?.connect(withTimeout: 10)
}
catch let e {
print(e.localizedDescription)
}
}
}
Once we reached till here, we have forgot most important thing.
without confirming delegate of stream our XMPPController
wont able to receive any callbacks, add following lines in init
self.stream?.addDelegate(self, delegateQueue: DispatchQueue.main)
XMPPStreamDelegate
as set of delegate functions among them we will use only couple of, add following code as below
extension XMPPController: XMPPStreamDelegate {
func xmppStreamDidConnect(_ sender: XMPPStream) {
print("Stream Connected")
try! stream?.authenticate(withPassword: password!)
}
func xmppStreamDidAuthenticate(_ sender: XMPPStream) {
print("Stream: Authnticated")
stream?.send(XMPPPresence())
}
}
Once xmppStreamDidConnect(:XMPPStream)
is connected, we are making sure that authentication should initiate & on authentication xmppStreamDidAuthenticate(:XMPPStream)
will receive callback
Entire code is available on github repo
https://github.com/momin96/Mobile-Chat-App
Posted on December 21, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.