Build a SwiftUI Chat Messaging App

Let's have a look at how to get started with the SwiftUI Chat SDK by building an example messaging app.

By going through our tutorial you will learn everything you need to get started with our SwiftUI SDK to build an iOS chat app. Once we are done, you will have created a chat application that is fully functional and ready for you to build upon.

Creating a project

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

To start with the SwiftUI SDK, open Xcode and create a new project.

  • Create a new Swift project in Xcode 13
  • Choose iOS from the list of platforms
  • Choose the "App" template
  • Use SwiftUIChatDemo for the project name
  • Select "SwiftUI" in the Interface option

Image shows Xcode 13 SwiftUI app project being created

We are going to use the Swift Package Manager to fetch the SDK. If you'd like, the SDK can also be installed with CocoaPods. You can find more information on using CocoaPods on the SDK doc pages.

  • Select "Add Packages…" in File menu
  • Paste the URL https://github.com/getstream/stream-chat-swiftui
  • In the option "Dependency Rule" choose "Branch", in the single text input next to it, enter "main" Image shows Xcode 13 package selection with a Github URL and a repository branch
  • Choose "Add Package" and wait for the dialog to complete
  • Only select "StreamChatSwiftUI" and select "Add Package" again Image shows Xcode 13 package selection with a Github URL and a repository branch

You now have an empty project for your chat app with the SwiftUI SDK as a dependency. Let's get started by displaying some content.

Displaying a List of Channels

The Stream SwiftUI SDK builds on top of the low-level Stream SDK. The low-level SDK facilitates a lot of the basic functionality you will need to create a chat application. And based on that functionality the SwiftUI SDK provides convenient UI Components allowing you to quickly display a channel list.

Add an AppDelegate to our project

The first step is to have an AppDelegate available in your SwiftUI App. We will need some of its life cycle methods to correctly setup our SDK.

  • Create a Swift file called AppDelegate, part of the SwiftUIChatDemo target
  • Replace the entire contents of the AppDelegate.swift file with the following.

Connect the AppDelegate to the app

We now have a class defined that implements the UIApplicationDelegate protocol. But before we can move on, we need to let the app know about it.

To do that we need to add a couple of things in the Swift file SwiftUIChatDemoApp.app

  • Open up the Swift file SwiftUIChatDemoApp.
  • Add the StreamChat and StreamChatSwiftUI imports to the top of the file.
  • Add the property appDelegate to the body of this class. Notice it is decorated with the property wrapper UIApplicationDelegateAdaptor.

The property wrapper UIApplicationDelegateAdaptor declares our AppDelegate to the iOS SDK. Doing so causes our AppDelegate to receive the life cycle callbacks happening within the life cycle of our app.

The end result should look like this:

Create StreamChat and ChatClient instances

Now we have our AppDelegate in place. It is time to start using the Stream SDK. To do that we need to do a couple of things:

  • Add a streamChat variable to the body of the AppDelegate class. Assigning a value will happen later in our implementation.
  • Add a ChatClient property to our implementation. This requires a ChatClientConfig.
  • Define a ChatClientConfig and pass it as a parameter to the ChatClient.

Here is the AppDelegate class with the above additions.

The StreamChat class is the central object in our SwiftUI Chat SDK. It is available for use in other areas of our SDK through a dependency injection system. We will explain how to conveniently get a reference to the StreamChat object later in this tutorial.

We will need to create a ChatClientConfig with an apiKey and an applicationGroupIdentifier. You can grab your API Key from https://getstream.io/dashboard/

The applicationGroupIdentifier is an App Group ID and is an iOS concept that you will need to use if you want to share credentials between your app bundle and any extensions you want to add to your messaging app later on. So it is a good idea to configure your application group from the start.

More information is available here and here.

Note: When you create your App Group, it is formed by appending your bundle ID to the group. For example, since you call this app SwiftUIChatDemo your bundle identifier will be something like this: group.com.organization.SwiftUIChatDemo where com.organization is your organization identifier used when creating the app.

Connecting the user

The next step is to get user credentials and feed these into the SDK and connect to our backend as an authenticated user.

To keep things simple we will be working with some hardcoded credentials in this tutorial.

To get a chat going, here’s what you need to do:

  • Initialise the StreamChat client.
  • Add a connectUser function.
  • Call the connectUser function from the body of application(_:didFinishLaunchingWithOptions:)

Let's apply all of the above to the contents of the AppDelegate.swift file. Here is the finished result:

Did you remember the fact that the chatClient variable was defined with a lazy property initialiser? And notice how calling into this property for the first time also creates the ChatClient instance.

After creating and assigning the StreamChat object we need to connect our hardcoded user. This will require a token to be submitted when connecting the user.

Note: You can also generate the token for this user from https://getstream.io/chat/docs/ios-swift/token_generator/?language=swift make sure to use the luke_skywalker as user id and the correct API Key Secret that we generated above

The chat client connects the user to our backend with some hard-coded user information and the token.

If anything is wrong, we log it to the console.

This is all you need to do to make sure our SDK is started and connected to our chat backend. But we still need to do something to present a chat UI to the end-user.

Presenting a chat user interface

As mentioned we still need to present a user interface to the user. To do that there is just one thing left to do.

  • Open your chat app's starting point, the file SwiftUIChatDemoApp.swift and replace the line ContentView() with `ChatChannelListView().

The completed code will look like this

Now run your project.

Let's review

Let's look back at all the things we just did:

  • First, we create an AppDelegate implementation. By default the project created by Xcode does not contain this. We need to initialise our SDK somewhere and the function didFinishLaunching on the AppDelegate is very convenient for this.
  • Within the AppDelegate we define a few things.
    • A streamChat variable to contain the main interface to our SDK.
    • A chatClient variable containing a ChatClient configured with an API key and an application group identifier. This API key points to a tutorial environment, but you can sign up for a free chat trial to get your own later.
  • During the launch of the app the didFinishLaunching function is executed and the connectUser() function is called. The connectUser() function "connects" a user with some hardcoded settings. In an actual implementation, you would obtain the user's information and fetch a Token through a login flow. 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.
  • In the SwiftUIChatDemoApp the existence of the App Delegate is declared with the @UIApplicationDelegateAdaptor property wrapper. This ensures iOS knows about our App Delegate.
  • The SwiftUIChatDemoApp declares the body of the app to be a WindowGroup scene containing a ChatChannelListView. The ChatChannelListView is one of the standard views provided by our SDK able to display a list of chat channels. The documentation about Querying Channels covers this in more detail.

Channel List Chat interface of an example SwiftUI chat app

Adjusting appearance through theming

A lot of the features of the SwiftUI Chat SDK can be modified through theming. It offers a quick and easy way to add basic branding and style to your chat implementation. Let's get a taste of what is possible.

Open up the file AppDelegate.swift. Look for the the application(_:didFinishLaunchingWithOptions:) function and make this function look like the following code sample:

Now run the app and see your changes.

Unthemed screenshot

Themed screenshot

Chat Message Customization

What if you want to do a more intricate customisation? Our SwiftUI SDK supports that too.

In this section, we will add an overlay on top of the chat message view.

To do that we need to do a couple of things:

  • Open up the AppDelegate file.
  • At the end of the file, add a new class: CustomViewFactory
  • At the end of the file, add a new class: CustomMessageTextView
  • Add a parameter to the ChatChannelListView instantiation, passing the CustomViewFactory as an argument.

Something of interest here is how we provide dependencies to our own and your custom views.

Currently these are the injectable values.

Next, open up the Swift file SwiftUIChatDemoApp.swift.

Add a parameter to the ChatChannelListView instantiation. So this line should be changed in the body variable getter.

Make sure it looks like this.

Run the app. You should now see your modifications on the message views.

Unthemed screenshot

Displaying Custom Attachment Views

Imagine certain pieces of content in your chat messages carry special meaning. A bit like a URL, it shows a preview and clearly entices the user to interact with the content. As a simple example, we will create a Custom Attachment display for messages containing email addresses. It illustrates how you can create modifications to the display of a message based on the content of the message.

Create a new Swift file called CustomAttachment. Put the following content in this new file.

This does two things. It defines our CustomAttachmentView, which is displaying a chat message with an envelope icon. The CustomMessageResolver detects if there is something in the chat message resembling an email address. Obviously, detecting an email address is more complicated, but that's outside of the scope of this tutorial.

The intended effect is to let the CustomMessageResolver detect if there is a reason to display the CustomAttachmentView.

We have the logic to detect an email address, and we have the view that is supposed to render this. Now we only need to configure the SDK to actually do this for us. To do that, we need to tell the SDK we have a CustomMessageResolver.

Email address Custom Attachment display

Open up the AppDelegate.swift file and find the line that creates the Utils instance, it should be right before the creation of the StreamChat instance.

This is the line you need to replace.

First create the CustomMessageResolver and pass it into the Utils constructor.

It should look like this.

Finally, to hook things up, we need to implement yet another factory method in your CustomViewFactory in the AppDelegate.swift file.

Now run the app and send a message with an email address in its contents.

There is more information on how to work with Custom Attachment Views when sending messages in our documentation.

Congratulations!

By completing this SwiftUI chat app tutorial you in fact created a fully functional chat experience. You learned how easy it is to customise the look and feel of the experience to make everything look and feel exactly how you would want.

The completed example app of this tutorial is available on GitHub as well.

To get started with the integration of chat into your own app, sign up for our free chat trial, and get your own API key to build with!

Final Thoughts

We have shown you how to build a fully functioning SwiftUI based app with our chat app tutorial. On top of that you now know how easy it is to add your own theme to the app and even fully customize key components.

Both the chat SDK for SwiftUI 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 iOS 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 SwiftUI for adding chat to your project? Either good or bad, we’re looking for your honest feedback so we can improve.

Kiddom logo

We’ve been going at lightspeed to build more communication functionality into Kiddom. The only way to achieve this in four months was to do a chat integration with Stream because we needed to do it reliably and at scale.

Head of Product, Kiddom profile picture

Nick Chen

Head of Product, Kiddom

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 about $ Activity Feeds

Enterprise

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

Learn more about $ Enterprise