iOS Chat With The Stream Swift SDK

Ready to get started? We are going to over everything you need to build an iPhone chat app with the Stream iOS SDK written in Swift. At the end of the tutorial, you will have created a fully functional Chat application that you can continue to build on.

Looking for more? We also recently published articles on Stream Chat Push Notifications, Comparing Chat API Pricing; and for feeds please check out our React Native Activity Feeds which details using our Activity Feed React Components. Thanks!

Creating a project

The completed app for each step of the tutorial is available on GitHub.

To get started with the iOS Chat SDK, open Xcode and create a new project.

  • Create a new Swift project in Xcode 12
  • Choose iOS from the list of platforms
  • Choose the "App" template
  • Use ChatDemo for the project name
  • Select Storyboard in the User Interface options

Image shows Xcode 12 App project being created

In this tutorial we are going to use Swift Package Manager as the dependency manager. The SDK can also be installed with CocoaPods, you can find more information about that on the SDK doc pages.

  • Open ChatDemo.xcodeproj
  • Select the option "Add Package Dependency" in File > Swift Packages
  • Paste the URL:
  • Press next, Xcode will look for the repository
  • Pick the latest available version on 4.x
  • Press next and wait for Xcode to download the dependency
  • Add both StreamChat and StreamChatUI packages to the project

Image shows Xcode 12 Swift Package Dependency

Displaying a List of Channels

Stream provides a low-level client, offline support, and convenient UI components to help you quickly build your messaging interface. In this section, we'll be using the UI components to quickly display a channel list. The first thing which we will do is to create a globally accessible shared instance of the Stream Chat Client and initialize its connection when the app starts. Next, we will fetch the channels which our user participates it and display it.

First, open the AppDelegate.swift file and add this extension to ChatClient at the top of the file:

Next, open up SceneDelegate.swift add import StreamChat at the top of the file and change the scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) method to the following:

Next, open ViewController.swift and change its content to this:

Let's have a quick look at the source code shown above:

  1. We initialize the shared ChatClient using an API key. This API key points to a tutorial environment, but you can sign up for a free Chat trial to get your own later.
  2. We create and connect the user using ChatClient.connectUser method and use a pre-generated user token, in order to authenticate the user. In a real-world application, your authentication backend would generate such a token at login / signup and hand it over to the mobile app. For more information, see the Tokens & Authentication page.
  3. We use the DemoChannelList component and initialize the channelListController controller with a ChannelListQuery. We’re using the default sort option which orders the channels by last_updated_at time, putting the most recently used channels on the top. For the filter, we’re specifying all channels of type messaging where the current user is a member. The documentation about Querying Channels covers this in more detail.

Channel List Chat interface for iOS

Creating a Chat Experience

Next we will create a DemoChannelVC view controller so that we can show how you can customize the channel screen.

(File > New > File > Cocoa Touch Class > DemoChannelVC) and open it in your editor.

Last step before running the app again, open the SceneDelegate and make these two changes:

  1. Append this at the top after the other imports
  1. Call applyChatCustomizations right before the initialization of ChatClient

When you run the application now you will be able to open channels from the list as well and try all built-in chat features.

Before moving to the next section, let's look at how we added the channel screen to the application:

  1. First we added the channel list view controller with a navigation controller. This allows the SDK to navigate from the channel list to the channel screen.
  2. We added a new view controller and subclassed ChatChannelVC the VC that provides the channel functionality
  3. We configured StreamChat to use our DemoChannelVC class. The SDK exposes most of the UI configuration on the Components.default object. This kind of changes are best done when the application is starting.

Chat Features

Congrats on getting your chat experience up and running! Stream Chat provides you with all the features you need to build an engaging messaging experience:

  1. Offline support: send messages, edit messages and send reactions while offline
  2. Link previews: generated automatically when you send a link
  3. Commands: type / to use commands like /giphy
  4. Reactions: long-press on a messages to add a reaction
  5. Attachments: use the paperclip button in MessageInputView to attach images and files
  6. Edit message: long-press on your message for message options, including editing
  7. Threads: start message threads to reply to any message

Stream’s API is powered by Go, RocksDB and Raft. The API tends to respond in less than 10ms and powers activity feeds and chat for over a billion end users.

Some features are hard to see in action with just one user online. You can open the same channel on the web and try user-to-user interactions like typing events, reactions, and threads.

Chat Message Customization

In the previous step we subclassed the ChatChannelVC and inherited a fully-functional and styled chat screen. This is a good starting point, let's now look at how we can customize the chat experience:

  1. Change message styles using attributes
  2. Create a custom attachment view
  3. Build your own views on top of the controllers provided by StreamChat

The first customization is fairly simple, components expose many attributes to handle the most common cases. Changing colors, font and images is very simple. The SDK collects allows you to make theming changes using the Appearance.default object.

To see this in practice, go back to SceneDelegate.swift and update the applyChatCustomizations function to looks like this:

The Appearance object exposes all colors, fonts and images used by components. This makes it very easy to apply theme changes consistently across the entire application. Similar to Components you need to to make changes to theming as early as possible in the application life cycle.

Customized Green Message List Chat

Creating Custom Attachment Views

There may come a time when you have requirements to include things in your chat experience that we don't provide out-of-the-box. For times like this, we provide two main customization paths: you can either reimplement the entire message component and display a message how you like, or you can use custom attachment views. We'll look at this latter approach now.

You could use this to embed a shopping cart in your chat, share a location, or perhaps implement a poll. For this example, we'll keep it simple and customize the preview for images shared from Imgur. We're going to render the Imgur logo over images from the domain.

As a first step, download the Imgur logo and drop the file inside Assets.xcassets using Xcode.

After that we are going to do the following:

  1. Create a custom view to display the image, and the Imgur logo overlay
  2. Create the AttachmentInjectorView class that adds out custom view to the message layout and initialize it with the content
  3. Create a custom AttachmentViewCatalog class, this is the class that is responsible for selecting the right view for a message attachment
  4. Register the custom catalog class to the Components object

The Custom Attachment View

You can place this code in a new file or simply add it to ViewController.swift

Here we added a UIView class called ImgurImageAttachmentView, this view class exposes a computed property content to hold and represent the attachment. Most of the code is just UIKit boilerplate code to render the labels and the Imgur logo on top of the image attachment.

The Custom AttachmentInjectorView

You can place this code right after the ImgurImageAttachmentView code.

The ImgurImageAttachmentViewInjector is a subclass of AttachmentViewInjector and wraps our custom view class. The two life-cycle methods contentViewDidLayout and contentViewDidUpdateContent are called by the SDK, this is where we set up our custom class with the right layout and with the content.

The Custom AttachmentViewCatalog

You can place this code right after the ImgurImageAttachmentViewInjector code.

The SDK uses the AttachmentViewCatalog to pick the appropriate AttachmentViewInjector for each message's attachments. Our subclass first checks if the message has any link attachment with images coming from the '' host and returns the custom injector for them.

Lastly, you need to configure the SDK to use the MyAttachmentViewCatalog. To do this you need update the applyChatCustomizations function from SceneDelegate.swift.

When you run your app, you should now see the Imgur logo displayed over images from Imgur. You can test this by posting an Imgur link like this one:

This was, of course, a very simple change, but you could use the same approach to implement a product preview, shopping cart, location sharing, polls, and more. You can achieve lots of your message customization goals by implementing a custom attachment View.

If you need even more customization, you can also implement custom message views for the entire message object.

Imgur Logo overlay on the in-app messaging chat interface

Creating a Typing Status Component

The channel list component shows typing indicators out of the box, in this example we are going to handle typing events ourselves and show our own.

The ChatChannelVC class is as a delegate of the ChatChannelController controller and conforms to the ChatChannelControllerDelegate protocol.

This protocol allows delegates to receive channels updates including changes to the list of typing users, the latter via this method:

Now that we know this, we can override the implementation from ChatChannelVC and write our own. This is how the DemoChannelVC.swift file should look like:

You can open the same channel on the web and try this using a different user.


In this iOS in-app messaging tutorial, you learned how to build a fully functional chat app on iOS. You also learned how easy it is to customize the behavior and build any type of chat or messaging experience.

Remember, you can also check out the completed app for the tutorial on GitHub.

If you want to get started on integrating chat into your own app, sign up for a free Chat trial, and get your own API key to build with!

To recap, our iOS Chat SDK consists of two frameworks which give you an opportunity to interact with Stream Chat APIs on a different level:

  • StreamChat - The official low-level Swift SDK for Stream Chat. It allows you to make API calls and receive events whenever something changes on a user or channel that you’re watching.
  • StreamChatUI - Builds on top of the low level client and provides fully custom UI, this library is your best starting point.

The underlying chat API is based on Go, RocksDB, and Raft. This makes the chat experience extremely fast with response times that are often below 10ms.

Final Thoughts

In this chat app tutorial we built a fully functioning iOS messaging app with our iOS SDK component library. We also showed how easy it is to customize the behavior and the style of the iOS chat app components with minimal code changes.

Both the chat SDK for iOS and the API have plenty more features available to support more advanced use-cases such as push notifications, content moderation, rich messages and more. Please check out our Android tutorial too. If you want some inspiration for your app, download our free chat interface UI kit.

Give us Feedback!

Did you find this tutorial helpful in getting you up and running with iOS for adding chat to your project? Either good or bad, we’re looking for your honest feedback so we can improve.

Next Steps

Start your 30-Day Chat trial to try out all our Chat product has to offer. No commitment or credit card required. If you want a custom plan or have questions, we are eager to talk with you.

Activity Feeds

Build any kind of feed without the headache of scalability or reliability of your feeds.

Learn more →

99.999% Uptime SLA, Industry leading compliance and security best practices.

Learn more →