> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-angular-v5-docs-update.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Typing Indicators

> Send and receive real-time typing indicators in conversations using the CometChat iOS SDK.

<Accordion title="AI Integration Quick Reference">
  ```swift theme={null}
  // Start typing indicator
  let typing = TypingIndicator(receiverID: "UID", receiverType: .user)
  CometChat.startTyping(indicator: typing)

  // Stop typing indicator
  CometChat.endTyping(indicator: typing)

  // Listen for typing events
  extension VC: CometChatMessageDelegate {
    func onTypingStarted(_ typingDetails: TypingIndicator) { }
    func onTypingEnded(_ typingDetails: TypingIndicator) { }
  }
  ```
</Accordion>

## Send a Typing Indicator

### Start Typing

Use `startTyping()` with a [`TypingIndicator`](/sdk/reference/auxiliary#typingindicator) object to notify the receiver that you're typing.

<Tabs>
  <Tab title="Swift (User)">
    ```swift theme={null}
    let typingIndicator = TypingIndicator(receiverID: "cometchat-uid-2", receiverType: .user)
    CometChat.startTyping(indicator: typingIndicator)
    ```
  </Tab>

  <Tab title="Objective-C (User)">
    ```objc theme={null}
    TypingIndicator *typingIndicator = [[TypingIndicator alloc]initWithReceiverID:@"cometchat-uid-2" receiverType:ReceiverTypeUser metadata:nil];
    [CometChat startTypingWithIndicator:typingIndicator];
    ```
  </Tab>

  <Tab title="Swift (Group)">
    ```swift theme={null}
    let typingIndicator = TypingIndicator(receiverID: "group-guid-1", receiverType: .group)
    CometChat.startTyping(indicator: typingIndicator)
    ```
  </Tab>
</Tabs>

`startTyping()` returns `void` — the typing indicator is sent as a fire-and-forget operation.

### Stop Typing

Use `endTyping()` to notify the receiver that you've stopped typing.

<Tabs>
  <Tab title="Swift (User)">
    ```swift theme={null}
    let typingIndicator = TypingIndicator(receiverID: "cometchat-uid-2", receiverType: .user)
    CometChat.endTyping(indicator: typingIndicator)
    ```
  </Tab>

  <Tab title="Objective-C (User)">
    ```objc theme={null}
    TypingIndicator *typingIndicator = [[TypingIndicator alloc]initWithReceiverID:@"cometchat-uid-2" receiverType:ReceiverTypeUser metadata:nil];
    [CometChat endTypingWithIndicator:typingIndicator];
    ```
  </Tab>

  <Tab title="Swift (Group)">
    ```swift theme={null}
    let typingIndicator = TypingIndicator(receiverID: "group-guid-1", receiverType: .group)
    CometChat.endTyping(indicator: typingIndicator)
    ```
  </Tab>
</Tabs>

`endTyping()` returns `void` — the typing indicator is sent as a fire-and-forget operation.

<Note>
  Use the `metadata` property of [`TypingIndicator`](/sdk/reference/auxiliary#typingindicator) to pass additional custom data. Retrieve it with `metadata` on the receiver side.
</Note>

## Real-time Typing Indicators

Use `onTypingStarted` and `onTypingEnded` in `CometChatMessageDelegate` to receive typing events.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    extension YourViewController: CometChatMessageDelegate {

        func onTypingStarted(_ typingDetails: TypingIndicator) {
            print("User started typing")
            print("Sender: \(typingDetails.sender?.name ?? "")")
            print("Receiver ID: \(typingDetails.receiverID)")
            print("Receiver Type: \(typingDetails.receiverType)")
        }

        func onTypingEnded(_ typingDetails: TypingIndicator) {
            print("User stopped typing")
            print("Sender: \(typingDetails.sender?.name ?? "")")
        }
    }

    // Register the delegate:
    CometChat.messagedelegate = self
    ```
  </Tab>

  <Tab title="Objective-C">
    ```objc theme={null}
    @interface ViewController ()<CometChatMessageDelegate>
    @end

    @implementation ViewController

    - (void)viewDidLoad {
        [super viewDidLoad];
        CometChat.messagedelegate = self;
    }

    - (void)onTypingStarted:(TypingIndicator *)typingDetails {
        NSLog(@"Typing started received successfully");
    }

    - (void)onTypingEnded:(TypingIndicator *)typingDetails {
        NSLog(@"Typing ended received successfully");
    }

    @end
    ```
  </Tab>
</Tabs>

The received [`TypingIndicator`](/sdk/reference/auxiliary#typingindicator) object contains:

| Property       | Type                                    | Description                      |
| -------------- | --------------------------------------- | -------------------------------- |
| `sender`       | [`User`](/sdk/reference/entities#user)? | User object of the person typing |
| `receiverID`   | `String`                                | UID of user or GUID of group     |
| `receiverType` | `ReceiverType`                          | `.user` or `.group`              |
| `metadata`     | `[String: Any]?`                        | Custom data sent with indicator  |

<Note>
  Typing indicators are transient and not persisted. The receiver must be online to receive them.
</Note>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Delivery & Read Receipts" icon="check-double" href="/sdk/ios/delivery-read-receipts">
    Track when messages are delivered and read
  </Card>

  <Card title="Transient Messages" icon="bolt" href="/sdk/ios/transient-messages">
    Send ephemeral real-time messages like live reactions
  </Card>
</CardGroup>
