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

# Message Privately

> Start private one-to-one chats from CometChat iOS UI Kit group conversations with message options, user lookup, and chat navigation.

Enable users to start a private one-on-one chat with a group member directly from a group chat screen using CometChat's UIKit for iOS.

## Overview

The Message Privately feature allows users to long-press a message in a group chat and select **Message Privately** to transition into a private conversation with the original sender. This streamlines side discussions and follow-ups without requiring manual user searches.

## Prerequisites

Before implementing this feature, ensure you have:

1. Completed [Getting Started](/ui-kit/ios/getting-started) setup
2. CometChat UIKit v5+ installed
3. User logged in with `CometChatUIKit.login()`

## Components

| Component                                   | Description                                                      |
| ------------------------------------------- | ---------------------------------------------------------------- |
| `CometChatMessageList`                      | Displays group messages and handles long-press to show options   |
| `CometChatMessageOption`                    | Defines the **Message Privately** option in the context menu     |
| `MessageDataSource`                         | Supplies the `messagePrivatelyOption` in the options array       |
| `CometChatMessageListViewModel`             | Manages UI state, including `hideMessagePrivatelyOption`         |
| `CometChatMessages`                         | Entry point for rendering or pushing the private chat interface  |
| `CometChat.getUser(UID:onSuccess:onError:)` | Retrieves the `User` object for the selected message sender      |
| `CometChatUIEvents.openChat(user:group:)`   | Opens the chat interface for a user or group                     |
| `UIViewController` (Navigation)             | Pushes or presents the private chat screen (`CometChatMessages`) |

## Integration Steps

### Step 1: Control Option Visibility via ViewModel

Dynamically show or hide **Message Privately** based on app context:

```swift lines theme={null}
import CometChatUIKitSwift

// Control visibility of the Message Privately option
public var hideMessagePrivatelyOption: Bool = false {
    didSet {
        // Sync with view model
        viewModel.hideMessagePrivatelyOption = hideMessagePrivatelyOption
    }
}
```

This ensures the option only appears when appropriate (e.g., based on user permissions).

**File reference:** [`CometChatMessageList.swift`](https://github.com/cometchat/cometchat-uikit-ios/blob/v5/CometChatUIKitSwift/Components/Message%20List/CometChatMessageList.swift)

### Step 2: Handle Private Chat Navigation

Retrieve the sender and initiate a private 1-on-1 chat:

```swift lines theme={null}
import UIKit
import CometChatSDK
import CometChatUIKitSwift

func startPrivateChat(with selectedMessage: BaseMessage) {
    // Get the sender from the selected message
    if let user = selectedMessage.sender {
        // Open the private chat using CometChatUIEvents
        DispatchQueue.main.async {
            CometChatUIEvents.openChat(user: user, group: nil)
        }
    }
}

// Alternative: Manual navigation with user fetch
func startPrivateChatManual(with selectedMessage: BaseMessage) {
    guard let uid = selectedMessage.sender?.uid else { return }
    
    // Fetch the user object
    CometChat.getUser(UID: uid) { [weak self] user in
        guard let user = user else { return }
        
        DispatchQueue.main.async {
            // Navigate to the private chat screen
            let messagesVC = CometChatMessages()
            messagesVC.set(user: user)
            self?.navigationController?.pushViewController(messagesVC, animated: true)
        }
    } onError: { error in
        print("Error fetching user: \(error?.errorDescription ?? "")")
    }
}
```

This automates the transition from group context to private conversation.

**File reference:** [`CometChatMessageList.swift`](https://github.com/cometchat/cometchat-uikit-ios/blob/v5/CometChatUIKitSwift/Components/Message%20List/CometChatMessageList.swift)

## Implementation Flow

| Step | Action                                                   |
| ---- | -------------------------------------------------------- |
| 1    | Long-press a group message in `CometChatMessageList`     |
| 2    | Options menu appears with **Message Privately**          |
| 3    | User taps **Message Privately**                          |
| 4    | App gets `User` from `message.sender`                    |
| 5    | Opens chat via `CometChatUIEvents.openChat(user:group:)` |
| 6    | Pushes `CometChatMessages` onto the navigation stack     |

## Customization Options

### Styling

Override `CometChatMessageOption` UI elements:

```swift lines theme={null}
// Customize the message option appearance
let privateOption = CometChatMessageOption(
    id: "message-privately",
    title: "Message Privately",
    icon: UIImage(systemName: "person.fill"),
    backgroundColor: .systemBlue
)
```

### Availability

Control visibility via the view model:

```swift lines theme={null}
// Hide the option for specific scenarios
viewModel.hideMessagePrivatelyOption = true
```

### Extend Options

Add additional actions in `MessageDataSource.getMessageOptions(for:)`:

```swift lines theme={null}
func getMessageOptions(for message: BaseMessage) -> [CometChatMessageOption] {
    var options = [CometChatMessageOption]()
    
    // Add message privately option
    if !hideMessagePrivatelyOption {
        options.append(messagePrivatelyOption)
    }
    
    // Add custom options
    options.append(customOption)
    
    return options
}
```

## Edge Cases

| Scenario               | Handling                                                   |
| ---------------------- | ---------------------------------------------------------- |
| Blocked users          | Hide option if the sender is in block list                 |
| Existing conversations | Reuse existing thread via `getConversationWith`            |
| Unavailable users      | Skip option or show disabled state if user data is missing |

## Error Handling

| Error Type       | Solution                                             |
| ---------------- | ---------------------------------------------------- |
| Block state      | Catch errors from `CometChat.getUser` and alert user |
| Network failures | Present retry or toast on navigation errors          |
| Invalid data     | Disable option if `sender.uid` is nil                |

## Additional Notes

* This feature is only available in **group chat** screens (`CometChatMessageList`)
* The option is hidden automatically in direct/private chat views

## Feature Matrix

| Feature                  | Component / Method                     | File(s)                                                                                                                                                                                                                                                                                                                              |
| ------------------------ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Show options menu        | `getMessageOptions(for:)`              | [`MessageDataSource.swift`](https://github.com/cometchat/cometchat-uikit-ios/blob/v5/CometChatUIKitSwift/Components/Shared/Framework/MessagesDataSource.swift)                                                                                                                                                                       |
| Toggle Message Privately | `viewModel.hideMessagePrivatelyOption` | [`CometChatMessageList.swift`](https://github.com/cometchat/cometchat-uikit-ios/blob/v5/CometChatUIKitSwift/Components/Message%20List/CometChatMessageList.swift), [`MessageListViewModel.swift`](https://github.com/cometchat/cometchat-uikit-ios/blob/v5/CometChatUIKitSwift/Components/Message%20List/CometChatMessageList.swift) |

## Related Components

* [Message List](/ui-kit/ios/message-list) - Display messages in conversations
* [Users](/ui-kit/ios/users) - Display user list
* [Conversations](/ui-kit/ios/conversations) - Display conversation list

<CardGroup cols={2}>
  <Card title="Sample App" href="https://github.com/cometchat/cometchat-uikit-ios/tree/v5/SampleApp">
    Explore this feature in the CometChat SampleApp
  </Card>

  <Card title="UIKit Source" href="https://github.com/cometchat/cometchat-uikit-ios/blob/v5/CometChatUIKitSwift/Components/Message%20List/CometChatMessageList.swift">
    Browse the message list component
  </Card>
</CardGroup>

## Related Guides

<CardGroup cols={2}>
  <Card title="Users" icon="user" href="/ui-kit/ios/users">
    Display and manage users
  </Card>

  <Card title="Conversations" icon="comments" href="/ui-kit/ios/conversations">
    View and manage conversations
  </Card>

  <Card title="Group Members" icon="user-group" href="/ui-kit/ios/group-members">
    View group membership
  </Card>
</CardGroup>
