> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/ably/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Getting started: Chat with Swift

This guide will help you get started with Ably Chat in a new iOS Swift application built with SwiftUI.

You'll learn how to create chat rooms, send messages, and implement realtime features like typing indicators and presence.

## Prerequisites

1. [Sign up](https://ably.com/signup) for an Ably account.

2. Create a [new app](https://ably.com/accounts/any/apps/new), and get your first API key.

3. Create a new iOS project with SwiftUI in Xcode.

4. Add the Chat dependency to your project using Swift Package Manager:
   * In Xcode, go to **File > Add Package Dependencies**
   * Enter the repository URL: `https://github.com/ably/ably-chat-swift`
   * Select the latest version and add it to your target

## Step 1: Set Up Ably

In production, you should use [token authentication](/docs/auth/token) to avoid exposing your API keys publicly.

Replace the contents of your `ContentView.swift` file:

<Code>
  ```swift theme={null}
  import Ably
  import AblyChat
  import SwiftUI

  struct ContentView: View {
      private let roomName = "my-first-room"

      @State private var chatClient: ChatClient

      init() {
          let realtimeOptions = ARTClientOptions()
          realtimeOptions.key = "{{API_KEY}}"
          realtimeOptions.clientId = "my-first-client"
          let realtime = ARTRealtime(options: realtimeOptions)

          let chatClient = ChatClient(realtime: realtime)
          self._chatClient = State(initialValue: chatClient)
      }

      var body: some View {
          VStack {
              Text("Hello Chat App")
                  .font(.headline)
                  .padding()
          }
      }
  }
  ```
</Code>

## Step 2: Create a Room and Send Messages

Add functionality to create a room and send messages:

<Code>
  ```swift theme={null}
  struct ContentView: View {
      private let roomName = "my-first-room"
      @State private var chatClient: ChatClient
      @State private var room: Room?
      @State private var messages: [Message] = []
      @State private var newMessage = ""

      init() {
          let realtimeOptions = ARTClientOptions()
          realtimeOptions.key = "{{API_KEY}}"
          realtimeOptions.clientId = "my-first-client"
          let realtime = ARTRealtime(options: realtimeOptions)

          let chatClient = ChatClient(realtime: realtime)
          self._chatClient = State(initialValue: chatClient)
      }

      var body: some View {
          VStack {
              List(messages.reversed(), id: \.id) { message in
                  Text("\(message.clientID): \(message.text)")
              }
              
              HStack {
                  TextField("Type a message...", text: $newMessage)
                      .textFieldStyle(RoundedBorderTextFieldStyle())

                  Button("Send") {
                      Task {
                          await sendMessage()
                      }
                  }
                  .disabled(newMessage.isEmpty)
              }
              .padding()
          }
          .task {
              await setupRoom()
          }
      }

      private func setupRoom() async {
          do {
              let chatRoom = try await chatClient.rooms.get(named: roomName)
              try await chatRoom.attach()
              self.room = chatRoom

              setupMessages(room: chatRoom)
          } catch {
              print("Failed to setup room: \(error)")
          }
      }

      private func setupMessages(room: Room) {
          room.messages.subscribe { event in
              withAnimation {
                  switch event.type {
                  case .created:
                      messages.append(event.message)
                  default:
                      break
                  }
              }
          }
      }

      private func sendMessage() async {
          guard !newMessage.isEmpty, let room = room else { return }

          do {
              _ = try await room.messages.send(withParams: .init(text: newMessage))
              newMessage = ""
          } catch {
              print("Failed to send message: \(error)")
          }
      }
  }
  ```
</Code>

## Next Steps

* Understand [token authentication](/docs/auth/token) before going to production
* Read more about using [rooms](/docs/chat/rooms?lang=swift) and sending [messages](/docs/chat/rooms/messages?lang=swift)
* Find out more regarding [presence](/docs/chat/rooms/presence?lang=swift)

Explore the [Ably CLI](https://www.npmjs.com/package/@ably/cli) further, or check out the [Chat Swift API references](https://sdk.ably.com/builds/ably/ably-chat-swift/main/documentation/ablychat/) for additional functionality.
