TaCode Tuesdays: How to Build an iOS Chat Application using Swift (Part 1)

Posted by Alex Misevski on September 27, 2016

TaCode_Image_Week_13

Welcome back to TaCode Tuesdays! This is the only place you can find snippets of code for use in your very own text/voice apps, along with a weekly dose of taco puns. I’m a developer here at Zang and not only am I a big fan of tacos (if that wasn’t already apparent), I’m also a fan of open source. My goal is to share a new app idea each week that you're free to use “as is” or modify and use as the basis for your next app.

During the last two weeks, I outlined a two-factor authentication app for Android—you can check out PART 1 here and PART 2 here, and as always, if you’d like to learn how to get started on Zang, take a look at our very first post.

This week I’m going to kick off another multiple-part series that details how you can build an iOS chat application using the Swift programming language and Zang.

Since Apple first released Swift two years ago, an estimated 59 percent of developer using Realm mobile database have adopted it. Only 39 percent still use iOS’ native programming language, Objective C. In addition, user adoption of Swift has increased dramatically – including developers from multi-national corporations who use Swift as the backbone of their critical enterprise applications. In fact, IBM created a variation of the language for Linux servers and Google is seriously pondering using Swift for Android applications, including Facebook and Uber.

Why Are Developers Switching to Swift?

More developers are switching to Swift for iOS chat apps because it is more compact, faster, less prone to error, and, after Apple acquired it in 2014, it is now open-source in nature. Because of this, chat apps’ lines of code can be reduced by 50% and algorithms can be performed more quickly, especially in calculations. Swift beats C++ in this area, mainly due to the latter’s C API legacy.

iOS Chat App Design

This tutorial will show you how to build an iOS chat app using Swift with IP messaging, voice calls, and voice conference features. Before we start, note that three types of voice call methods for this chat app can be implemented using Zang API: app-to-app, app-to-phone, and phone-to-phone. So, let’s start!

The data flow diagram below shows the backend process of a chat application with IP messaging and voice call features. Upon logging in, a user can start receiving or sending messages through using a socket library. For the purpose of this guide, we recommend the use of Node.js. It is an open-source library that can be added to Swift in order to use IP messaging with Zang’s voice call API. You can download it for free here.

Figure 1: Chat Application using IP Messaging and VOIP PaaS (platform as a service) Data Flow Diagram

 

iOS_Swift_Image.png

A socket library provides interactivity between the Client ID of chat participants. When a socket is created, the program specifies the address domain and the socket type allowing them to communicate through the internet. Essentially, two processes can communicate with each other, provided that their sockets are of the same domain. The client program sends data packet (send/receive) into the socket library (in this case Node.js) which sends the messages for polling.  

To enable the user to initiate a voice call, your Swift code will conduct a REST enabled call to Zang to initiate a call. Node will be responding in JSON format and Swift will parse it accordingly and display it on the UI storyboard that you created for your voice call.

Now that you have a high-level view of how to build the app, let’s get to the specifics. Before you start building your chat application in Swift, there are some prerequisites:

  1. Familiarity with Swift programming language
  2. Access to a Zang Account for voice chat capability
  3. Apple Developer Account membership
  4. Familiarity with socket programming and JavaScript frameworks
  5. RESTful API Platform to provide two ways (inbound/outbound) of communication. In this case, Node.js and SMS/Voice services

This guide has two parts. The first part will show you how to create an iOS chat app using Node.js IP messaging and the second part will demonstrate how to build voice call and voice conference feature using Zang’s API. After you’ve completed these two main features you will have to integrate them to create an iOS app that is capable of both IP messaging and voice calls.

Let's Get Started

The first part involves eight steps, starting from installation of required software down to developing a table-less design for the chat app user interface.

Step 1: Open your terminal window and install the following:

  • Install Node.js
  • Install Node.js Socket (npm install websocket)
  • Install Nano (npm install nano)

Step 2: Open Xcode and create a single view chat project.

Select Swift as the programming language.

Step 3: Open the ViewController.swift file.

Use the following code snippet as a guide for setting up your web view:

override func viewDidLoad()
{
     super.viewDidLoad()
     // Do any additional setup after loading the view, typically from a nib (NexSTEP Interface Builder).
     let url = NSURL (string: "LOCAL HOST PATH"); // example http://localhost/index.html
     let requestObj = NSURLRequest(URL: url!);
     myWebView.loadRequest(requestObj);
}
 

Step 4. Inside your index page you can use the following as a template to build a basic chat messaging feature:

$(document).ready(function ()
{
   var connection,
       username = 'Your desired username',
       password = 'Your desire password',
       historyCounter = 0,
       totalmembers = {},
    
   function connect ()
   {
       connection = new WebSocket('URL TO YOUR WEB SERVICE NODE JS'); // example: http://localhost/mychatroom

 

       connection.onopen = function ()
       {
           states[activeState].onopen();
       };

 

       connection.onmessage = function (message) {
           try {
               addMsg(JSON.parse(message.data));
           }
           catch (e) {
               addLine(null, 'Exception while handling a server message: ' + e.toString());
           }
       };<
 
       connection.onclose = function () {
           states[activeState].onclose();
       };
   }

 

   function loginKeypress(event)
   {
       if (13 !== event.keyCode) return;
       username = jqNickname.val();
       password = jqPassword.val();
       if (!username) jqNickname[0].focus();
       else if (!password) jqPassword[0].focus();
       else {
           jqWaiting.css('display', '');
           jqNickname.unbind('keydown', loginKeypress);
           jqPassword.unbind('keydown', loginKeypress);
           connect();
       }
   }

 

   function inputKeypress(event) {
       var line;
       if (13 === event.keyCode) {
           line = jqLine.val();
           if (line.length === 0) return;
           jqLine.val('');
           connection.send(JSON.stringify({ 'type': 'line', 'line': line }));
       }
   }

 

   var status = {
           'login': {
               'start': function () {
                   jqChatroom.css('display', 'none');
                   jqWaiting.css('display', 'none');
                   jqLogin.css('display', '');
                   jqNickname.val('');
                   jqPassword.val('');
                   jqNickname[0].focus();
                   activeState = 'login';
                   jqNickname.bind('keydown', loginKeypress);
                   jqPassword.bind('keydown', loginKeypress);
               },
               'onopen': function () {
                   connection.send(JSON.stringify({ 'type': 'login', 'username': username, 'password': password }));
               },
               'messageHandlers': {
                   'state': function (msgObj) {
                       var i, history, users;
                       states.chat.start();
                       history = msgObj.history;
                       jqHistory.empty();
                       historyCounter = 0;
                       for (i = 0; i < history.length; i++) addMsg(history[i]);
                       users = msgObj.users;
                       clearMembers();
                       for (i = 0; i < users.length; i++) addMember(users[i]);
                   }
               },
               'unhandledMessage': function (msgObj) {
                   connection.close(4000, 'Unhandled message type');
               },
               'onclose': function () {
                   states.login.start();
               }
           },

 

           'chat': {
               'start': function () {
                   jqLogin.css('display', 'none');
                   jqWaiting.css('display', 'none');
                   jqChatroom.css('display', '');
                   jqHistory.empty();
                   historyCounter = 0;
                   activeState = 'chat';
                   jqLine.bind('keydown', inputKeypress);
               },
               'onopen': function () {
                   connection.close(4001, 'Connection opened while chatting');
               },
               'messageHandlers': {
                   'line': function (msgObj) {
                       addLine(msgObj.nick, msgObj.line);
                   },
                   'join': function (msgObj) {
                       addLine(null, 'Priklopil: ' + msgObj.nick);
                       addMember(msgObj.nick);
                   },
                   'leave': function (msgObj) {
                       addLine(null, 'Odklopil: ' + msgObj.nick);
                       removeMember(msgObj.nick);
                   }
               },
               'unhandledMessage': function (msgObj) {
                   connection.close(4000, 'Unhandled message type');
               },
               'onclose': function () {
                   addLine(null, 'Connection closed');
                   jqLine.unbind('keydown', inputKeypress);
               }
           }
       },
       activeState = 'login';

 

   states.login.start();
});
 

This tutorial is continued in the next TaCode Tuesday article How to Build an iOS Chat Application using Swift (Part 2).  If you have any thoughts about the app or just want to share your own taco-related thoughts, you can comment below. If you want a reminder, sign up to get notifications of new blog posts.

Start building on Zang

Topics: Communication Apps, Ideas, TaCode Tuesday, cPaaS