Build an iMessage Clone With the Stream Chat iOS SDK

Bahadir Oncel
The Startup
Published in
5 min readApr 18, 2020

In this tutorial, we’ll build a functional clone of iMessage using Stream Chat iOS SDK. Building a messaging app used to be difficult, but in this tutorial, you’ll get a chat experience up and running in roughly 20 minutes.

If you get lost during this tutorial, you can check:

The result of our application will look similar to the following screenshots:

Let’s get started.

Install Cocoapods

For this tutorial, we are going to use CocoaPods as a dependency manager. For convenience, we also publish the SDK on Cartage and Swift Package Manager.

If you do not currently have CocoaPods installed, or your cocoapods is outdated, you can update/install it by running the following command:

$ sudo gem install cocoapods

Cloning the iMessage Clone Starter Branch

Start by cloning the starter branch of the WhatsApp Clone Github repo:

$ git clone -b starter git@github.com:GetStream/stream-imessage-clone.git

Once cloned, let’s go ahead and install the dependencies with the pod installcommand:

$ pod install --repo-update

After all of our pods are installed, open the Xcode workspace:

$ open iMessageClone.xcworkspace

Note: The starter branch sets up the project and dependencies so we can jump right into coding! You can also create a new project; in that case, please make sure your Podfile is the same as that in the repo.

Configuring The Stream Chat Client

The first thing we need to do is configure our StreamChat Client with our API key. Open your AppDelegate file and edit your didFinishLaunchingWithOptionsfunction, so that it looks like this:

Note: You can find your API key in the Stream Dashboard. To create an application, head over to https://getstream.io/chat/ and create a free account. Once created, click on the “Chat” tab within the dashboard. You will see that an application has been pre-provisioned for you. Within that application, you can find your credentials (API key and secret).

After that, you can put your api secret and desired user id in this token generator to get the user token: https://getstream.io/chat/docs/token_generator/

Now that you’ve done that let’s go ahead and move on.

Creating the Contacts Screen

We’ll start by creating a contacts (chats) view controller and make it look like that in the iMessage app. We’ll name it ContactsViewController.

Please create a new swift file and name it as shown above.

Note: If you’ve created a new project, rename your ViewController.swift and use it instead.

Then, paste the following contents inside:

Next, open Main.storyboard and change the view controller class to ContactsViewController:

Then embed the entry view controller inside a navigation controller:

After you’ve embedded a navigation controller, select your navigation item in a navigation controller and tick “Prefers Large Titles”:

Now to display the chat messages! Paste these lines into your ContactsViewController:

Now, if you run the app, you’ll see that our contacts screen looks very similar to iMessage, and we have only used the customization options provided by Stream Chat:

Our contacts cells lack the blue dot showing the unread status of a chat, the chevron symbol next to the dates, and the date text is not formatted to look like iMessage. Let’s fix that.

For things like this — which Stream Chat does not provide an API for — we can subclass Stream Chat’s classes and quickly add custom logic. Let’s do that.

Create a new file named ContactListCell.swift and paste these contents:

We’ve extended Stream Chat’s ChannelTableViewCell to add our components (unread indicator and date accessory), and we’ve overridden update(date:) function to display our date string.

To be able to use our new cell, we need to add a few lines of code inside of ContactsViewController.

Inside viewDidLoad, before tableView.tableFooterView = nil line, add the following:

and paste this new function:

You only need to register your cell type, dequeuing is done automatically by our SDK and overriding updateChannelCell is enough for customizing your cell.

Now if you run the application, you’ll see that we were able to implement the missing features:

Great!

Building the Messaging Screen

Now, let’s move onto the Messaging screen. Currently, we haven’t touched it any of the code yet, so it looks nothing like iMessage at this point:

With that said, let’s go ahead and start customizing our screen.

Paste this code inside ContactsViewController's setupStyles function:

If you run the application now, you’ll see colors and message bubbles look like those that are seen in iMessage. However, the navigation bar title is buggy, as it displays a significantly larger title. Further, we are missing a few UI buttons that iMessage has built-in.

To fix the “large title situation” (and implement our custom navigation item title), we have to subclass Stream Chat’s ChatViewController.

Create a new swift file and name it MessagesViewController.swift. Then, paste in the contents:

Once you’ve added the new class ChatNavigationTitleView, you'll have successfully imitated iMessage’s title view.

To use our new MessagesViewController, we need to add this into our ContactsViewController:

This completes our work in ContactsViewController.If you run the application, you'll see that our messages screen looks a lot more like iMessage now. But we still have some UI buttons to add to make it look more like iMessage. Let's add them now.

Add these in your MessagesViewController as properties:

Then, add the setupUI function:

Lastly, add this call to your viewDidLoad (as the last call):

and now run the app:

Wrapping Up

We have now completed the messaging section of our iMessage clone, using Stream Chat’s API. If you want to take this application further, make sure to check out the Stream docs to find out all the features that are available to you.

This concludes our tutorial. Happy coding.

--

--