Sockets+MVVM in Swift

Krishna Soni
Mindful Engineering
9 min readJan 22, 2020
towardsdatascience.com

The data transmission between the server and client is a really convoluted process. We want instantaneous updates from the server when something happens, but the big problem is how we can send and receive updates from the server?

Generally, To communicate with a server, We use RESTful APIs. But what happens when we need real-time updates from the server? We need to keep polling the server, which is worst idea IMHO.

Polling server not only invite loads on the server, it will cause issues to the app too, App will suffer from issues like- excessive battery consumption and lagging apps, Constant API calling can be interrupted due to reason like network error, slow internet, etc. and we won’t get the updated data as we expect.

So, To overcome this we use Sockets. So whenever we want constant updates from the server without calling the APIs, We use Socket programming.

Introduction

Socket programming is a real-time, Bidirectional, Event-based communication.

1. Real-time:- Client will get the instant update when something happens on the server

2. Bidirectional:- Client can both send and receive the update to the server.

3. Event-Based communication:- This means a client can send any event to the server when something notable happens.

Here the client can be anything like:- A mobile, desktop or a web application.

The socket communication depends on the client-server logic, where a persistent connection between a server and a client always exists. The server provides a dedicated port where the client gets connected to it.

Once the connection is established, all connected devices can communicate with each other on this dedicated port.

As the default behavior, every connected client to the server will automatically get the update without any additional request to the server. When any update is sent to that port by a server, the recipient client will instantly receive it.

For now, Let’s understand the basic mechanism behind the socket programming, The server provides a dedicated port to the client and once the client gets connected to it they can communicate with each other on this respective port.

Overview

Implementing the connection to a socket and communicating through it with a server is not that straight forward task, Even though the whole idea sounds fascinating, there might exist several hurdles until it’s possible to achieve usable communication.

Thankfully, here comes into play a really handful framework that takes charge of all the connection issues behind the scene and makes the socket-based communication a real piece of cake. It’s called Socket.IO.

I highly recommend you to pay a visit to the official website here, so you understand what is it all about and how it works.

As we need a server for the communication so we will set up the server in our own computer (Localhost).

Server setup

Let me give you a brief description of how we can set up the server in our local system

1. We have to install Node.JS in our system if it’s not already installed. To download the Node.JS, go here and get the latest version of it.

Simply double click on downloaded stuff and follow the screen instructions.

2. Download the src-server-socket.zip file from here and uncompressed it. This folder has all packages and code to make the sample server.

3. We need a local IP address so open Terminal and type ifconfig command and hit run.

Copy the 192.168.X.X if you are on local area network, Or some other IP address if you are not on LAN.

4. Navigate to the src-server-socket folder

cd Desktop/src-server-socket

If you have a different path or folder name then change the above command with the respective folder and pathname.

Then start the server with this command

node index.js

If you see the message “listening on *:3001” which means the server is using port number 3001.

To stop the server, just hit CTRL+C keys.

You can also change the port number from index.js which is located in src-server-socket folder.

Demo App Preview

In this, we will discuss how we can use the Socket.IO library in iOS and how we can achieve real-time communication with the server.

Yes, We’ll discuss everything in detail but let me give you a brief description of the project.

We are going to use MVVM design pattern in this , We have three main classes

JoinChatViewController

ChatListViewController

ChatDetailViewController

In the JoinChatViewController user simply join the chat room by clicking on the “JOIN CHAT” button.

JoinChatViewController.swift

ChatListViewController class has the participant list who joined the chat room. Also, there is an “Exit” button to leave the chat room.

ChatListViewController.swift

ChatDetailViewController class for a chat where users can send messages to each other.

ChatDetailViewController.swift

Socket.IO Library Integration

Now it’s time to add the Socket.IO library to our project, There are several ways to add the Socket.IO library in our project, Go here and choose your suitable way to add this library into the project, Here I used this library by CocoaPods.

After successfully adding the library, Let’s configure the all needed stuff for the project.

I created a class SocketHelper.swift class, This will have all socket related functions that are going to use in our project.

I created a singleton instance as we are using this class in so many places.

static let shared = SocketHelper()

I defined some constant variables for the socket and we will see next how to use it.

let kHost = “http://192.168.1.43:3001"
let kConnectUser = “connectUser”
let kUserList = “userList”
let kExitUser = “exitUser”

There is method configureSocketClient() which is configuring the socket for us and also make it private because we are not going to use it outside the class.

Here the socketURL is our server URL, In my case, it is a combination of IP address and port number.

let kHost = “http://192.168.1.43:3001"

This class has two other methods establishConnection() and closeConnection()

The establishConnection() is used to connect the socket to the server.

The closeConnection() is used to disconnect the socket from the server.

After connection setup let’s move a bit ahead. The next methods are about the chat room. So we will see how we can join and leave the chat room.

Here is the method joinChatRoom(…) with the nickname parameter. This “nickName” is a user name with users want to join the chat room.

Similarly the leaveChatRoom(…) for the leave the chat room.

The emit(…) method of the socket object is what we need for sending the message to the server using the Socket.IO client library.

The next method participantList(…) to get the list of connected users.

As we used the on(…) method of the socket object. This will return an array of results and an acknowledgment.

Here I created a “User” model class that will store the user properties. Also created Application+Extension class to convert an object into jsonString and Data.

Here is the complete code of the Application+Extension class.

Next two methods sendMessage(…) and getMessage(…) for send and receive the message.

The sendMessage(…) with a message and nickName parameters.

The getMessage(…) to get real-time messages.

Here I used the “Message model to handle the message response.

Here is the complete code of the SocketHelper class.

The SocketHelper class setup has been completed. This class has all the needed code that is going to be used in view-controller classes. As we created this class instance is a singleton so we can easily access this class everywhere in the whole project.

Now it’s time to move on view-controller classes. When we launch the application the first screen will be JoinChatListViewController class. This screen has a “JOIN CHAT” button and on by clicking on it will show an alert with two buttons and a Textfield.

It will ask for a name which is your chat room name. As we didn’t handle the login flow so make sure this will be unique for all.

On the “OK” button from the alert, we are calling the joinChatRoom(…) which is implemented in SocketHelper class.

After successfully join the chat room called the method moveToNextScreen(…) to move the user on the next screen.

The next screen will be ChatListViewController class. In this class, I created a tblChatList variable and created a class “ChatListTableView.swift” so this class will have all tableView related functionality. Later We will discuss more about it.

We have one “Exit” button in the navigation to leave the chat room. So here we are calling the leaveChatRoom() Method from SocketHelper class and in completion of this method just send back the user to the back screen.

ChatListViewController class is also a method configureTableView(), This method will configure all the table view related actions which will be performed from “ChatListTableView.swift

Let’s have a look into ChatListTableView.swift class.

I created a view-model instance of the ChatViewModel.swift class. This view-model will have all business logic.

private var chatViewModel: ChatViewModel = ChatViewModel()

There is a method fetchParticipantList() to fetch the joined user list in the chat room.

Here we removed the current device user (Or we can say Login user) from the list as we are not showing current device users in the list.

We used the array of users to show in the table view. This array wrapped with a generic class “KxSwift”.

So whenever something changed in this array it will automatically notify where it is implemented.

In the ChatListTableView.swift class there is a method configureViewModel() to configure the ChatViewModel.swift.

Here we subscribe the arrUsers by chatViewModel.arrUsers.subscribe so when something has changed in arrUser this clouser will call and inside the closure just reload the table view. So it will automatically update the table when any user has Join/Leave the channel.

Here is the complete code of the ChatListTableView.swift class.

On the tableView(_ tableView:, didSelectRowAt indexPath: ) method we are sending user to next ChatDetailViewController screen. This is the final and main screen of our demo project. In this user can send/receive the messages or we can say users can communicate with each other.

As we are following the MVVM design pattern so here also we have a parent class (ChatDetailsTableView.swift) of the TableView (tblChat) which will have all table view related functionalities. We are getting some properties “User” and “nickName” from the previous class.

ChatDetailViewController class has some basic UIKit components, A TableView to show the messages, a TextView and a send button.

Now, Let’s discuss about the ChatDetailsTableView.swift class.

This class has two properties, A MessageViewModel who’s holding all business logic regarding chat and a “nickName” property.

We are calling the method configureViewModel() to configure the MessageViewModel.swift and similarly ChatListTableView.swift class subscribing the array of messages.

So, Whenever the “arrMessage” gets updates, This clouser will call automatically, Inside the clouser there is a method “scrollToBottom(animated:)” this method will automatically scroll the table view at the bottom and it is implemented in TableView+Extension.swift class.

Here we are calling the method “getMessagesFromServer()” which is implemented in MessageViewModel.swift class.

In the MessageViewModel.swift class, We have an array of Message which is wrapped by the KxSwift.

There is method “getMessagesFromServer()” calling the “SocketHelper.shared.getMessage” method which implemented in SocketHelper class. When any new message sends by the users this method clouser will call automatically and update the table view.

Conclusion

We finally have reached at the end of this article, let us go through what we built so far. It was quite easy to work with socket programming in swift while following the MVVM design pattern.

We can say the moving part of this application is a bare-bones chat application that can send and receive messages to & from a server in real-time. A socket is such a super-weapon, it is suitable for all ways to communicate with the servers for sure.

I hope you found what you read is useful and that you have learned something new form this article.

Thanks For Reading !! 🙂

You can find source-code of this article over here.

Inspirations are taken from here

--

--