Chat Application Using Xmpp Swift Tutorial
The final project is available for download from the Github repository
What is XMPP?
Extensible Messaging and Presence Protocol (XMPP) is an open XML technology for real-time communication as explained in the official site info section.
Main Benefits of using it is its feature such as Presence to notify user state as well as being extensible therefore allowing you to extend its capibility to send Images and Video too. Other solutions do not provide such advance features and to add user states such as typing/away is very hard to implement yet core to a chat app. Therefore, XMPP is a good choice for chat apps.
Roadmap of Tutorial
Before we move on to explaining things and to code, a little review of what this tutorial will cover will be good.
1) How To Run A Ejabberd Server On Your Mac/Localhost
We will be running a ejabberd xmpp server for our chat app. Steps to install and configure it will be given.
2) Registering A User Through Terminal
It’s good to get familiar with the working of server using terminal for future use. You can read and explore more on ejabberd site.
3) Using/Registering Account On Adium (A Jabber Client)
To be able to chat between two user, we need to have our app (first client) and another client for user2. Adium will act as the second user
4) Log In The User On The Server With The iOS App
Connecting and Login with the server plus handling errors will be explained.
5) Sending To/Fro Message To The Other User Through iOS App.
This part will have us code for messages coming from other user as well as sending message from the app.
Step 1. Downloading ejabbered
We will be using ejabbered server for our app.
There are several xmpp servers available out there, Openfire being a popular alternative.
Go ahead and download the ejabbered community server installer from here.
• Run the Setup
• Install it to the Default Path which will be something like Applications/ejabbered/
on the Mac OS X.
• For the server name - you can use localhost
• Use Admin as the admin name and 12345 for the password for now
• ejabbered will install now. Click done at the final screen.
Step 2. Registering A User Through Terminal
Steps are also explained here for your reference https://docs.ejabberd.im/developer/install-osx/.
• Open a Terminal folder and cd into the ejabberd path.
For version 16.06 in Mac OS X. The command will be cd /Applications/ejabberd-16.06
• To run the server use the command. sbin/ejabberdctl live
• To register the user -> use the syntax register username servername pass.
The one i have used bin/ejabberdctl register user1 localhost pass
Step 3. Using/Registering Account On Adium (A Jabber Client)
Since our server is setup using a XMPP based protocol, we will be using a jabber client to connect to our server and check out how it performs. Go ahead and download Adium from https://adium.im/.
Install it and launch it, close any account assitant setup if it comes. Now you will see a screen something like this :
• Now open Adium preferences from the top menu.
• In Account click the add button at the bottom left and select xmpp jabber account
• Enter the username@host and then a pass - i kept 123
• A alert will come with the text “Requested URL was not found on this server”: Click ok. Now in the server - enter the host name i.e localhost in our case
Clicking request new account will now register this and you will have the adium client setup for this.
Step 4. Log In The User On The Server With The iOS App
Now with our server setup and adium running with the second user, time to move to Xcode to build the chat app.
Open up Xcode and create a new project named XMPP. We will be using swift and cocoapods in the project so make sure to be versed in them before progressing.
Setup Pods
Init the pod for the project. Below is the podfile that i used
Open up the workspace xcodeProj now.
ViewController Code
First import the XMPPFramework.
The code is very basic. We first declare a variable stream
of type XMPPStream
in global scope.
Further, we initialize the stream in viewDidLoad
method, add the delegate so that we can receive event callbacks for connection successful or any failure.
We will set a JID so that we can uniquely identify our user. Since we have already registered one user using terminal, we will use the user1@localhost here.
Next we call the try stream.connectWithTimeout(30)
method to actually connect to our ejabberd
server.
Adding the Delegate methods
Most of the above methods are self explanatory. In the xmppStreamDidConnect
method, we try to authorize our user with the password.
Here we use 123 as the password which we had set when registering the user.
Run the app and if everything has been followed correctly, you will see the auth Done log in the console.
Step 5. Sending To/Fro Message To The Other User Through iOS App.
Declare a few more variables
These will be used to maintain the roster of our user account. That way you can maintain which users you have contacted with previously and many more things.
Now in viewDidLoad
add the new code which is highlighted above using //new code comments.
We initialize our xmppRoster
, then we activate the stream on it.
A button is added which will simply be used to send message to other user.
sendMessage
function is shown below:
here we create a instance of XMPPMessage
class and the message type to be of chat (there are many other types of message types like subscribe which you will see shortly) and for the senderJID, we use the user2 JID which we have running in Adium.
Using the stream object we send the message.
Implementing Presence
Last important thing to do is to have the presence implemented so that we can recieve messages too. XMPP is based on presence and stanza concept which you can read further on wiki or its official site.
For user2 to contact us, we need to detect the presence events it send and act accordingly. Implement the following delegate method
Here we filter out the presenceType, stream JID username and then the presence sender username. This is done to filter out any presence from the same user to itself. Next we detect few individual presenceType such as available and subscribe. First time the user2 tries to contact us: we will recieve a subscribe presence and until we add that user to our roster, the message will not be recieved. Therefore, in the subscribe presence we add the presence sender to our roster and then the presence can be worked upon to retrieve messages.
Conclusion
Thank you for reading this far. For any questions you are welcome to ask in our chat room.
For further info
Next Steps
Please take a look at our other tutorials :)