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!

Installation

Stream Chat's iOS SDK is made up of two libraries: StreamChat, which provides low-level access to the Stream Chat API, and StreamChatUI. StreamChatUI is built on top of StreamChat and provides the high-level UI components that allow you to plug in the chat experience in your app with minimal coding required.

Note: StreamChatUI is currently in beta.

If you don't have an iOS project yet, open the section below.

Creating the iOS Project

Create a new Swift project in Xcode 12 with the "App" template using the project name ChatDemo.

Select Storyboard in the User Interface options.

Image shows Xcode 12 App project being created

Close the Xcode project for now.

Open a terminal and navigate to your project path:

cd ~/path/to/my/projects/ChatDemo/

To get started integrating Stream Chat in your iOS app, install the StreamChatUI dependency using one of the following dependency managers.

  1. CocoaPods
  2. Swift Package Manager
Installing CocoaPods (if you haven't)If you do not currently have CocoaPods installed, you can do so by running the following command:
sudo gem install cocoapods

Please note that if you already have CocoaPods installed, make sure you run the most recent version or you may receive errors later on in the development process.

sudo gem update cocoapods

Now that you are in your project directory and have ensured that CocoaPods is installed, let’s go ahead and install the Stream Chat SDK.

If your project doesn't contain a Podfile yet, initialize CocoaPods and create a Podfile:

pod init

In your project's Podfile, add: pod 'StreamChatUI', '~> 3.0-beta.4'. It should look similar to the snippet below.

target 'ChatDemo' do # Comment the next line if you don't want to use dynamic frameworks use_frameworks! # Pods for ChatDemo pod 'StreamChatUI', '~> 3.1' end

Now that we’ve modified our Podfile, let’s go ahead and install the project dependencies via the terminal with one simple command:

pod install --repo-update

The above command will generate the ChatDemo.xcworkspace file automatically.

With our workspace now containing our Pods project with dependencies, as well as our original project, let’s go ahead and move over to Xcode to complete the process.

User Authentication

After the SDK is installed, the next step is to decide how we'll handle authentication. The user can be a regular user, or it can be an anonymous or guest user with limited sets of permissions. A TokenProvider is the object that will hold your authentication strategy and will tell the ChatClient which user you're currently logged in with.

  1. Regular
  2. Guest
  3. Anonymous

Regular users are the way to go for a most chat apps. They must be authenticated with a JWT token generated with your app's secret key. Ideally, you'll generate the token in your backend and provide a closure to fetch it, but for testing purposes we provide a JWT generator and you can set the token statically. It's also possible to use development tokens, but they must be enabled for your app in the dashboard.

  1. Static
  2. Closure
  3. Development
/// A static token provider. Use it for testing purposes. let token = Token("USER_TOKEN") let tokenProvider = TokenProvider.static(token)

Configuration

The next step is to configure a ChatClient instance with your credentials and the tokenProvider from the previous step. The most simple way to do this is by extending the ChatClient class with a shared instance that will be used throughout your app (Singleton). It's also possible to create a chat instance in a convenient entry point and pass it down to your classes / view controllers. (Dependency Injection).

  1. Singleton
  2. Dependency Injection

To make a ChatClient singleton, we extend the ChatClient class with a static shared instance of itself.

/// 1: Extend the `ChatClient` class. extension ChatClient { /// 2: Add a `shared` static variable of its own type. static var shared: ChatClient! }

In the desired entry point, set the shared instance with the tokenProvider from the Authentication step. In this case, we're doing it in the AppDelegate's didFinishLaunchingWithOptions callback.

import StreamChat import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { /// 1: The token provider you created in the Authentication section. let token = Token("USER_TOKEN") let tokenProvider = TokenProvider.static(token) /// 2: Create a `ChatClientConfig` with the API key. let config = ChatClientConfig(apiKeyString: "YOUR_API_KEY") /// 3: Set the shared `ChatClient` instance with the config and the token provider. ChatClient.shared = ChatClient(config: config, tokenProvider: tokenProvider) return true } }

UI Components

After you have a ChatClient instance, you can present the UI components. The StreamChatUI import provides UIKit components while StreamChat provides combine wrappers that integrate seamlessly with SwiftUI. If SwiftUI is your preferred UI framework, consider following our SwiftUI Chat tutorial.

The default UIKit components provided are ChatChannelListVC and ChatChannelVC. Both of them should be pushed into UINavigationController stack to work properly.

  1. Channel List Screen
  2. Channel Screen

If your app supports more than one conversation at a time, it's a good idea to start with the ChatChannelListVC. It will present a list of channels based on the filter you set. Most likely, you'll filter for channels the current user is a member of as demonstrated in the snippet below.

Image shows the Channel List component

import StreamChat import StreamChatUI /// 1: Instantiate the `ChatChannelListVC`. let channelListVC = ChatChannelListVC() /// 2: Create a `ChannelListQuery` with a filter for channels that include the current user id. let query = ChannelListQuery(filter: .containMembers(userIds: ["USER_ID"])) /// 3: Set the `ChatChannelListVC`'s `ChatChannelListController`. channelListVC.controller = ChatClient.shared.channelListController(query: query)

The channel list screen will present the corresponding channel screen when the user presses one of the channel cells. At this point, you have a full chat implementation working in your app.

Dark Mode

You can expect all components to correctly support iOS's Dark Mode setting.

Image shows the channel list screen and channel screen in Dark Mdoe

Customization

It's possible to customize various aspects of the UIKit components. We've prepared a customization cheat sheet with common changes.

Final Thoughts

In this tutorial we learned how to build a fully functional iOS chat app using Swift. We also showed how easy it is to customize the behavior and build any type of chat or messaging experience.

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. Stream powers activity feeds and chat for over 500 million end users, so you can feel confident about our APIs.

Both the Swift Chat SDK and the Chat API have plenty more features available to support more advanced use-cases such as push notifications, content moderation, rich messages and more.

Don't forget! We have an Android Chat SDK as well!

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.