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

# Receive Messages

> Receive real-time messages, fetch unread messages, and retrieve message history using the CometChat iOS SDK.

<Accordion title="AI Integration Quick Reference">
  | Field         | Value                                                                                                                |
  | ------------- | -------------------------------------------------------------------------------------------------------------------- |
  | Key Classes   | `CometChatMessageDelegate`, `MessagesRequest.MessageRequestBuilder`                                                  |
  | Key Methods   | `onTextMessageReceived()`, `onMediaMessageReceived()`, `onCustomMessageReceived()`, `fetchPrevious()`, `fetchNext()` |
  | Delegate      | `CometChat.messagedelegate = self`                                                                                   |
  | Prerequisites | SDK initialized, user logged in                                                                                      |
</Accordion>

Receiving messages with CometChat has two parts:

1. Adding a [real-time listener](#real-time-messages) to receive messages while your app is running
2. Fetching [unread](#unread-messages) or [historical](#message-history) messages when your app starts up or the user scrolls back

## Real-Time Messages

Register a `CometChatMessageDelegate` to receive incoming messages as they arrive. Each callback receives the specific message subclass — [`TextMessage`](/sdk/reference/messages#textmessage), [`MediaMessage`](/sdk/reference/messages#mediamessage), or [`CustomMessage`](/sdk/reference/messages#custommessage).

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

      func onTextMessageReceived(textMessage: TextMessage) {
        print("TextMessage received successfully: " + textMessage.stringValue())
      }

      func onMediaMessageReceived(mediaMessage: MediaMessage) {
        print("MediaMessage received successfully: " + mediaMessage.stringValue())
      }

      func onCustomMessageReceived(customMessage: CustomMessage) {
        print("CustomMessage received successfully: " + customMessage.stringValue())
      }
    }
    ```
  </Tab>

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

    @implementation ViewController

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

    - (void)onTextMessageReceivedWithTextMessage:(TextMessage *)textMessage {
        NSLog(@"TextMessage received successfully: %@",[textMessage stringValue]);
    }

    - (void)onMediaMessageReceivedWithMediaMessage:(MediaMessage *)mediaMessage {
        NSLog(@"MediaMessage received successfully: %@",[mediaMessage stringValue]);
    }

    - (void)onCustomMessageReceivedWithCustomMessage:(CustomMessage *)customMessage {
        NSLog(@"CustomMessage received: %@",[customMessage stringValue]);
    }

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

Don't forget to set your view controller as the delegate in `viewDidLoad()`:

```swift theme={null}
CometChat.messagedelegate = self
```

<Warning>
  As a sender, you will not receive your own message in a real-time event. However, if a user is logged in on multiple devices, they will receive the event on the other devices.
</Warning>

## Missed Messages

Fetch messages that were sent while the app was offline using `MessagesRequest` with `setMessageId()` set to the last delivered message ID.

### Fetch Missed Messages of a particular one-on-one conversation

```swift theme={null}
let limit = 50
let latestId = CometChat.getLastDeliveredMessageId()
let UID = "cometchat-uid-2"

let messagesRequest = MessagesRequest.MessageRequestBuilder()
  .set(messageID: latestId)
  .set(uid: UID)
  .set(limit: limit)
  .build()

messagesRequest.fetchNext(onSuccess: { (messages) in
  for message in messages! {
    if let receivedMessage = (message as? TextMessage) {
      print("Message received successfully. " + receivedMessage.stringValue())
    } else if let receivedMessage = (message as? MediaMessage) {
      print("Message received successfully. " + receivedMessage.stringValue())
    }
  }
}) { (error) in
  print("Message receiving failed with error: " + error!.errorDescription);
}
```

### Fetch Missed Messages of a particular group conversation

```swift theme={null}
let limit = 50
let latestId = CometChat.getLastDeliveredMessageId()
let GUID = "cometchat-guid-1"

let messagesRequest = MessagesRequest.MessageRequestBuilder()
  .set(messageID: latestId)
  .set(guid: GUID)
  .set(limit: limit)
  .build()

messagesRequest.fetchNext(onSuccess: { (messages) in
  for message in messages! {
    if let receivedMessage = (message as? TextMessage) {
      print("Message received successfully. " + receivedMessage.stringValue())
    } else if let receivedMessage = (message as? MediaMessage) {
      print("Message received successfully. " + receivedMessage.stringValue())
    }
  }
}) { (error) in
  print("Message receiving failed with error: " + error!.errorDescription);
}
```

## Unread Messages

Fetch unread messages by adding `setUnread(true)` to the builder. Use `fetchPrevious()` to retrieve them.

```swift theme={null}
let limit = 50
let UID = "cometchat-uid-2"

let messagesRequest = MessagesRequest.MessageRequestBuilder()
  .set(unread: true)
  .set(limit: limit)
  .set(uid: UID)
  .build()

messagesRequest.fetchPrevious(onSuccess: { (messages) in
  for message in messages! {
    if let receivedMessage = (message as? TextMessage) {
      print("Message received successfully. " + receivedMessage.stringValue())
    } else if let receivedMessage = (message as? MediaMessage) {
      print("Message received successfully. " + receivedMessage.stringValue())
    }
  }
}) { (error) in
  print("Message receiving failed with error: " + error!.errorDescription);
}
```

## Message History

Fetch the full conversation history using `fetchPrevious()`. Call it repeatedly on the same request object to paginate.

```swift theme={null}
let limit = 50
let UID = "cometchat-uid-2"

let messagesRequest = MessagesRequest.MessageRequestBuilder()
  .set(limit: limit)
  .set(uid: UID)
  .build()

messagesRequest.fetchPrevious(onSuccess: { (messages) in
  for message in messages! {
    if let receivedMessage = (message as? TextMessage) {
      print("Message received successfully. " + receivedMessage.stringValue())
    } else if let receivedMessage = (message as? MediaMessage) {
      print("Message received successfully. " + receivedMessage.stringValue())
    }
  }
}) { (error) in
  print("Message receiving failed with error: " + error!.errorDescription);
}
```

<Note>
  The list of messages received is in the form of [`BaseMessage`](/sdk/reference/messages#basemessage) objects. A [`BaseMessage`](/sdk/reference/messages#basemessage) can be a [`TextMessage`](/sdk/reference/messages#textmessage), [`MediaMessage`](/sdk/reference/messages#mediamessage), or [`CustomMessage`](/sdk/reference/messages#custommessage). Use type casting to check the type.
</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 by recipients
  </Card>

  <Card title="Typing Indicators" icon="keyboard" href="/sdk/ios/typing-indicators">
    Show real-time typing status in conversations
  </Card>
</CardGroup>
