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

Posted by Alex Misevski on October 4, 2016


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.

Last week, I began detailing how you can build a chat application using Swift and Zang on iOS—so get started here if you're interested in this free code, 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 continue the series by walking through 4 more steps. Next week, I'll wrap everything up. I would recommend that you read the first post in the series before reading this post, otherwise it won't make any sense! Anyways, I ended on step 4 in the last post, so let's get right into step 5.

Step 5: Define your node variables and the response stream:

var http = require('http'),
   url = require('url'),
   path = require('path'),
   fs = require('fs'),
   nano = require('nano')('http://localhost:5115'),
   chatroomDb = nano.use('chatroom'),
   websocket = require('websocket'),<
   chatHistory = [],
   activeUsers = {};


var getContentType = function (extension) {
   var mimeType = mimeTypes[extension];
   return mimeType ? mimeType : 'application/octet-stream';


Step 6: Create a Node server for grabbing the method, URL, headers and body of requests. The function that's passed to createServer is called once for every HTTP request that's made against it, hence calling it the request handler.

var server = http.createServer(function (request, response) {
   var relativePath = url.parse(request.url).pathname,
       absolutePath = path.join(filesDir, relativePath);
   var handler = function (err, stats) {
       if (stats) {
           if (stats.isDirectory()) {
               absolutePath = path.join(absolutePath, 'index.html');
               fs.stat(absolutePath, handler);
           if (stats.isFile()) {
               response.writeHead(200, getContentType(path.extname(absolutePath)));
               var stream = fs.createReadStream(absolutePath);
       response.writeHead(404, {'Content-Type': 'text/plain'});
       response.write('Not found\r\n');
   console.log('HTTP request for ' + relativePath);
   fs.stat(absolutePath, handler);
server.listen(8080, function () {});


wsServer = new websocket.server({
   'httpServer': server


Step 7: Create the parser for accepting data request to and from:

wsServer.on('request', function (request) {
   console.log('New websocket connection from ' + request.origin);
   var connection = request.accept(null, request.origin);
   var username = null;


   connection.on('message', function (message) {
       if (message.type !== 'utf8') {
           console.log('Refusing a non-utf8 message');
       console.log('Processing message: ' + message.utf8Data);
       try {
           var m = JSON.parse(message.utf8Data);
           switch (m.type) {


               case 'login':
                   chatroomDb.get(m.username, function (err, body) {
                       if (err || (body.password !== m.password)) {
                       username = m.username;
                       addLine('join', username, null);
                       activeUsers[username] = {
                           'sendMessage': function (jsonMsg) {
                       var users = [], u;
                       for (u in activeUsers) users.push(u);<
                       connection.sendUTF(JSON.stringify({ 'type': 'state', 'history': chatHistory, 'users': users }));


               case 'line':
                   if (!username) {
                   addLine('line', username, m.line);
       catch (e) {


   connection.on('close', function (connection) {
       console.log('Connection closed');
       if (username) {
           delete activeUsers[username];
           addLine('leave', username, null);


console.log('Status: Running');


Step 8: After you have created your server swift web view, you can create a table-less design for your UI the resides on top of your web view, similar to this format:

<h1 id="heading">Chatroom</h1>
           <div id="outer">
               <div id="inner">
                   <div id="chat">
                       <div id="history">
                           <p><span class="nick">John: </span><span class="line">Hello there</span></p>
                           <p><span class="nick">Paul: </span><span class="line">What's up?</span></p>
                           <p><span class="nick">George: </span><span class="line">Welcome!</span></p>
                       <div id="input"><input id="line" type="text"></div>
                   <ul id="members">


Continue this tutorial in by reading TaCode Tuesdays: How to Build an iOS Chat Application using Swift (Part 3)we only have 3 more steps to go! 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