How to Build a Chat App with SwiftUI: Part 2 (Channels)
Tags: ios, swift, beginners, tutorial
Published: 2020-06-25 15:47:21

---
title: How to Build a Chat App with SwiftUI: Part 2 (Channels)
published: true
cover_image: https://i.imgur.com/Ld9zduE.png
tags: iOS, Swift, Beginners, Tutorial
canonical_url: https://getstream.io/blog/chat-app-swiftui-part2/
---

Note: Find a more up-to-date version of this article at: https://getstream.io/blog/chat-app-swiftui-part2/

In Part 1 of this series, we created a [simple chat application for iOS and macOS using SwiftUI](https://getstream.io/blog/chat-app-swiftui-part1/) and [Stream Chat's Swift SDK](https://github.com/getstream/stream-chat-swift), but it only had a single channel. In this tutorial, we'll improve on it by implementing a channels screen with three features: join, create, and search channels. Although [Stream Chat](https://getstream.io/chat/) provides a [suite of UIKit components](https://getstream.io/tutorials/ios-chat/), including those for channels, we'll use the low-level client to develop custom components with SwiftUI.

![Animation shows a channels screen. User creates then searches a channel.](https://i.imgur.com/LbPVsry.gif)

If you get lost during this tutorial, or want to get the completed code for Part 1, you can check the completed project in this [GitHub repo](https://github.com/getstream/stream-chat-swiftui-example). Branch `part1` has the code for Part 1.

## What you need
- iOS 13+
- Xcode 11+
- A [Stream](https://getstream.io/accounts/signup/) account
- Followed Part 1.

## Step 1: Update the Chat View

In the first part, we developed a Chat View that only displayed the "general" channel. Now we need to make it flexible to display any channel. Your ChatView.swift should look like this:

{% gist https://gist.github.com/cardoso/4ae9453eac775da09c6920b0e4ca8bb0 %}
(due to a bug in dev.to, if you're not seeing `ChatView.swift`, go to https://gist.github.com/cardoso/4ae9453eac775da09c6920b0e4ca8bb0)

Instead of the hard-coded "general" channel, that code defines an initializer for `ChatView` that takes an id and initializes the channel object with that id. Additionally, you'll want to replace the hard-coded snippet `.navigationBarTitle("General")` with `.navigationBarTitle(channel.id)`, so it displays the title correctly.

Before proceeding to the next step, let's also add `Client.shared.add(users: [Client.shared.user], to: channel, { _ in })` to the end of `onAppear` on `ChatView`, so we make sure every channel visited will show up in the channels view.

## Step 2: Create the Channels View

Now, we need a Channels View with the channels the user is part of, which will look similar to the following screenshot.

![Screenshot shows a simple channels screen running on the iPhone simulator](https://i.imgur.com/XeN6cCp.png)

Let's create a `ChannelsView.swift` file and paste the following contents. We'll leave the create channel and search functions for the next steps. 

{% gist https://gist.github.com/cardoso/ef9c3e35fd58aee200baae72bc97020d %}
(due to a bug in dev.to, if you're not seeing `ChannelsView.swift`, go to https://gist.github.com/cardoso/ef9c3e35fd58aee200baae72bc97020d)

In that snippet of code, we create a `List` where each item is a `NavigationLink` to the `ChatView`. The `onAppear` callback makes a query to the Stream service for the channels the current user is a member of, or, in case the `searchTerm` is not empty, we query all channels and filter out the ones that don't contain the searched string in the id. [[docs](https://getstream.io/chat/docs/query_channels/?language=swift)]

Note we're not handling the possible errors that can result from the query. In production, it would be best if you dealt with the possible errors.

## Step 3: Modify the Login View

This is a quick step: In Part 1, the Chat View was shown right after login. What we want now is to show the Channels View.

Just swap the destination where it says `NavigationLink(destination: ChatView(), tag: true, selection: $success) {` with `ChannelsView()`. 

## Step 4: Implement channel creation

After that small tweak to the Login View, let's implement the Create Channel function. First, go back to `ChannelsView.swift` and uncomment the `//createChannelView` in the body.

Now, we need to add the following property and methods.

{% gist https://gist.github.com/cardoso/36cb3a539951c94e208b248316574ff4 %}
(due to a bug in dev.to, if you're not seeing `ChannelsView.swift`, go to https://gist.github.com/cardoso/36cb3a539951c94e208b248316574ff4)

When the user presses the create button on the top right, it will set the `createTrigger`, which activates the display of the `createChannelView`. This view is a horizontal stack of a `TextField` and a `Button`, which, when pressed, runs the `createChannel` function. That function takes the contents of the text field and [creates a channel](https://getstream.io/chat/docs/initialize_channel/?language=swift) with that as the id, after that it [adds the current user](https://getstream.io/chat/docs/channel_members/?language=swift) to the channel.

Again, to keep the tutorial short, we're not presenting the possible errors, but in production, you should display some message.

## Step 5: Implement channel search

In Step 2, we already laid the grounds for the search to happen by specifying a different filter when `searchTerm` is not empty. Now we only need to build the UI, which will look similar to the screenshots below.

![Screenshots of the channel search function](https://i.imgur.com/ElD15w5.png)

First, go to `ChannelsView.swift` and uncomment `//searchView`. Next, define the following property and function.

{% gist https://gist.github.com/cardoso/7f8f868d36c37a1ec139ab9954883301 %}
(due to a bug in dev.to, if you're not seeing `ChannelsView.swift`, go to https://gist.github.com/cardoso/7f8f868d36c37a1ec139ab9954883301)

That code defines a horizontal stack of a `TextField` and a `Button`. When the user types something in the text field, the `loadChannels` function is triggered, showing the channels that contain the search term in their ids. At the same time, the clear button is displayed. When pressed, it resets the view back to the original state.

## Wrapping up

Congratulations! You've built a channels screen and learned a few functions to interact with the Stream API. Let's recap those: [`queryChannels`](https://getstream.io/chat/docs/query_channels/?language=swift) to display the list of channels, [`channel.create`](https://getstream.io/chat/docs/initialize_channel/?language=swift) to create a channel, and [`add(users: [], to: channel)`](https://getstream.io/chat/docs/channel_members/?language=swift) to add the user to a channel. Since this is the last part of this series, I encourage you to browse through SwiftUI's [docs](https://developer.apple.com/documentation/swiftui), Stream Chat's [docs](https://getstream.io/chat/docs/introduction/?language=swift), and experiment with the project you just built.