Using Pusher Chatkit with SlackTextViewController on iOS

Published Dec 26, 2017Last updated Feb 17, 2018

Nowadays many applications offer in-app chat and messenger features to their users. The in-app messenger can be useful for things like live support chatting or in-app messaging with other application users.

In this article, we are going to explore how to use Pusher Chatkit (which is in beta at the time of writing this article) and SlackTextViewCont roller to create a chat application.

TIP:SlackTextViewController is a drop-in UIViewController subclass with a growing text input view and other useful messaging features. It is meant to be a replacement for UITableViewController & UICollectionViewController.

Here is a screen recording of our application in action:

Requirements

To follow along with the tutorial, you will need the requirements listed below:

Creating our Chatkit Application

Go to the Chatkit page, create an account and create a Chatkit application from the dashboard.

Follow the “Getting Started” wizard until the end so it helps you create a new user account and a new chat room.

In that same screen, after you have completed the “Get Started” wizard, click on “Keys” to get your applications ‘Instance Locator’ and ‘Key’. You will need these values to make requests to the Chatkit API.

That’s all! Now let us create a backend that will help our application in communicating with the Chatkit API.

Creating a Node.js Backend for Pusher Chatkit

Before we create our iOS application, let us create a Node.js backend for the application. The application will talk to the backend to do things like retrieve the token required to make requests.

Open your terminal and in there create a new directory where the web application will reside. In this web application, we will define some routes that will contain logic for making requests to the Chatkit API.

Run the command below to create the directory that will contain our web application:

$ mkdir ChattrBackend

Create a new package.json file in the root of the directory and paste the contents below:

In the code above we have a sample Express application. The application has 2 main routes. The /users route creates a new user using the Chatkit API. The created user can then request a token using the /auth route. Tokens are used to validate the identity of a user making a request to the Chatkit API.

Finally, let us create a config.js file in the same root directory. This is where we will define the Chatkit keys. Paste the contents below into the file:

Remember to replace *PUSHER_CHATKIT_*``*INSTANCE_*``*LOCATOR* and *PUSHER_CHATKIT_KEY* with the actual values for your Chatkit application. You can find the values in the “Keys” section of the Chatkit dashboard.

Now we are done creating the Node.js application. Run the command below to start the Node.js application:

$ node index.js

TIP: You may want to keep the terminal window open and launch another terminal window to keep the Node.js server running.

Creating our iOS Application

Launch Xcode and create a “Single View App” project.

Installing Our Cocoapods Packages
When you have created the application, close Xcode and launch a new terminal window. cd to the root of the directory of your mobile application. Run the command below to initialize Cocoapods on the project:

$ pod init

This will create a new Podfile. In this file, we can define our Cocoapods dependencies. Open the file and paste the following:

NOTE:SlackTextViewController has a bug in iOS 11 where the text view does not respond to clicks**. Although it’s been fixed in version** 1.9.6, that version was not available to Cocoapods at the time of writing this article, so we had to pull the master in the Podfile.**

When the installation is complete, open the new .xcworkspace file that was generated by Cocoapods in the root of your project. This will launch Xcode.

Configuring our iOS Application
In Xcode, open the AppDelegate.swift file and replace the contents of the file with the following code:

In the AppConstants struct we have defined the ENDPOINT and INSTANCE_LOCATOR. The ENDPOINT is the URL to the remote web server where your Node.js application resides. The INSTANCE_LOCATOR contains the instance locator provided for your Chatkit application in the Pusher Chatkit dashboard.

Now let us focus on creating the storyboard and other parts.

Creating Our Application’s Storyboard and Controllers

Open the Main.storyboard file and, in there, we will create the application’s interface. We will have four scenes on our storyboard. These will look something like the screenshot below:

In the first View Controller scene, let’s create a LoginViewController and link it to the View Controller scene in the storyboard. Create the new View Controller and paste in the code below:

In the code above, we have defined two @IBOutlets that we will connect to the View Controller scene in the storyboard. In the prepare method, we prepare for the navigation to the RoomListTableViewController by setting the username property in that class. In the loginButtonPressed handler we fire a request to the Node.js application we created earlier to create the new user.

Open the storyboard and link the first scene to the LoginViewController class. Add a UIButton and a UITextField to the view controller scene. Now connect the UITextField to the textField property as a referencing outlet and also connect the UIButton to the loginButton property as a referencing outlet.

Next, add a Navigation Controller to the storyboard. Create a manual Segue between the View Controller and the Navigation Controller and set the ID of this segue to loginSegue.

Next, create a new controller called RoomListTableViewController. In the Main.storyboard file, set this new class as the custom class for the TableViewController attached to the Navigation Controller. Now in the RoomListTableViewController class, replace the contents with the following code:

This class is meant to show all the available chat rooms that users can connect to and chat on. Let’s see what some parts of the class do.

The first extension contains the initializers. In the viewDidLoad method we set up the controller title, activity indicator, and Pusher Chatkit.

In the initPusherChatManager, we initialize a tokenProvider which fetches a token from our Node.js endpoint. We then create a chatManager with our Chatkit application’s instance locator and the tokenProvider, and connect to Chatkit.

In the second extension, we override some table view controller methods. We do this so we can display the channel names in rows. In the last method of the second extension on line 100, we call the method performSegue(withIdentifier:"segueToRoomViewController", sender: self) which will navigate the page to a new View Controller.

The last extension has the prepare method. This prepares the View Controller we are navigating to before we get there. Now, let’s create the View Controller and the segue needed to access it.

For our last storyboard scene, create a RoomViewController class. In the Main.storyboard file, drag in a final View Controller to the board.

Set the custom class of the new view controller to RoomViewController. Also, create a manual segue from the table view controller to it and name the segue segueToRoomViewController:

Open the RoomViewController class and replace the contents with the following:

The class above extends SlackTableViewController which automatically gives it access to some cool features of that controller. In the code above, we broke the class into 5 extensions. Let’s take each extension and explain a little about what is going on in them.

In the first extension, we subscribe to the room, set the room name as the page title and configure the SlackTableViewController. In the configureSlackTableViewController method, we simply customise parts of our SlackTableViewController.

In the second extension, we override the table view controller methods; we set the number of sections, the number of rows, and also the Message to be shown on each row; and we also calculate the dynamic height of each cell depending on the characters the message has.

In the third extension, we have the didPressRightButton function which is called anytime the user presses send to send a message.

In the fourth extension, we have the functions available from the PCRoomDelegate. In the newMessage function we send the message to Chatkit and then we reload the table to display the newly added data.

In the fifth and final extension, we define functions that are meant to be helpers. The PCMessageToMessage method converts a PCMessage to our own Message struct (we will define this later). The sendMessage method sends the message to the Chatkit API. Finally, we have the messageCellForRowAtIndexPath method. This method simply gets the message attached to a particular row using the indexPath.

Now create a new class called MessageCell. This will be the View class where we will customise everything about how a single chat cell will look. In the file, replace the contents with the one below:

In the code above, we create a class that extends UITableViewCell. This class is going to be used by SlackTextViewController as the class for each message row. It was registered in the RoomsViewController when configuring the SlackTextViewController.

Testing Our Pusher Chatkit Application

To instruct your iOS app connect to your local Node.js server you will need to make some changes. In the info.plist file, add the keys as seen below:

With this change, you can build and run your application and it will talk directly with your local web application. Now you can run your application.

Conclusion

In this tutorial, we were able to create a simple chat application using SlackTextViewController and the power of the Pusher Chatkit SDK. Hopefully, you have learned a thing or two on how you can integrate Pusher Chatkit into existing technologies and how it can power messaging in your application.