> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-013b37f0.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Building A Conversation List + Message View

The **Conversation List + Message View** layout offers a modern two-panel chat experience. It's ideal for applications needing seamless switching between multiple conversations and chat windows—similar to **WhatsApp Web**, **Slack**, or **Microsoft Teams**.

***

## **User Interface Preview**

<Frame>
  <img src="https://mintcdn.com/cometchat-013b37f0/eXBBMbCp8GceLKEu/images/39abbd91-chat_experience_sidebar_message-6476f0d5e48fdff63caa68809e60486b.png?fit=max&auto=format&n=eXBBMbCp8GceLKEu&q=85&s=219bcd09c806102df923967ff2420ad0" width="1440" height="833" data-path="images/39abbd91-chat_experience_sidebar_message-6476f0d5e48fdff63caa68809e60486b.png" />
</Frame>

### **Key Components**

1. **Chat Header** – Displays user or group name, avatar, and back button.
2. **Message List** – Displays chat messages and real-time updates.
3. **Message Composer** – Allows sending of text, media, and reactions.

***

## **Step-by-Step Guide**

### **Step 1: Setup SceneDelegate.swift**

Ensure UIKit is initialized and the user is logged in before presenting the conversation view.

```swift SceneDelegate.swift highlight={15-17} lines theme={null}
import UIKit
import CometChatUIKitSwift
import CometChatSDK
import CometChatCallsSDK

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        guard let windowScene = (scene as? UIWindowScene) else { return }

        let uikitSettings = UIKitSettings()
            .set(appID: "<#Enter Your App ID Here#>")
            .set(region: "<#Enter Your Region Code Here#>")
            .set(authKey: "<#Enter Your AuthKey Here#>")
            .subscribePresenceForAllUsers()
            .build()

        CometChatUIKit.init(uiKitSettings: uikitSettings) { result in
            switch result {
            case .success:
                debugPrint("CometChatUIKit initialization succeeded")

                let uid = "cometchat-uid-1"

                CometChatUIKit.login(uid: uid) { loginResult in
                    switch loginResult {
                    case .success:
                        debugPrint("CometChatUIKit login succeeded")

                        DispatchQueue.main.async { [weak self] in
                            guard let self = self else { return }
                            self.setupConversationsView(windowScene: windowScene)
                        }

                    case .onError(let error):
                        debugPrint("Login failed: \(error.description)")
                    @unknown default: break
                    }
                }

            case .failure(let error):
                debugPrint("Initialization failed: \(error.localizedDescription)")
            }
        }
    }

    func setupConversationsView(windowScene: UIWindowScene) {
        let conversationsVC = CometChatConversations()
        let navController = UINavigationController(rootViewController: conversationsVC)

        conversationsVC.set(onItemClick: { [weak navController] conversation, _ in
            let messagesVC = MessagesVC()
            messagesVC.group = conversation.conversationWith as? Group
            messagesVC.user = conversation.conversationWith as? CometChatSDK.User
            navController?.pushViewController(messagesVC, animated: true)
        })

        window = UIWindow(windowScene: windowScene)
        window?.rootViewController = navController
        window?.makeKeyAndVisible()
    }
}
```

***

### **Step 2: Create MessagesVC.swift**

This view controller handles chat between users or within groups.

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

/// A view controller that displays a chat interface using CometChat components
class MessagesVC: UIViewController {
    
    // MARK: - Properties
    
    /// The user entity for one-on-one chats
    var user: User?
    
    /// The group entity for group chats
    var group: Group?
    
    // MARK: - UI Components
    
    /// Header view displaying user/group information
    private lazy var headerView: CometChatMessageHeader = {
        let view = CometChatMessageHeader()
        view.translatesAutoresizingMaskIntoConstraints = false
        // Configure for the appropriate conversation type
        if let user = user {
            view.set(user: user)
        } else if let group = group {
            view.set(group: group)
        }
        view.set(controller: self)
        return view
    }()
    
    /// Message input composer view
    private lazy var composerView: CometChatMessageComposer = {
        let composer = CometChatMessageComposer()
        composer.translatesAutoresizingMaskIntoConstraints = false
        // Configure for the appropriate conversation type
        if let user = user {
            composer.set(user: user)
        } else if let group = group {
            composer.set(group: group)
        }
        composer.set(controller: self)
        return composer
    }()
    
    /// List view displaying chat messages
    private lazy var messageListView: CometChatMessageList = {
        let listView = CometChatMessageList()
        listView.translatesAutoresizingMaskIntoConstraints = false
        // Configure for the appropriate conversation type
        if let user = user {
            listView.set(user: user)
        } else if let group = group {
            listView.set(group: group)
        }
        listView.set(controller: self)
        return listView
    }()
    
    // MARK: - Lifecycle Methods
    
    override func viewDidLoad() {
        super.viewDidLoad()
        configureView()
        setupLayout()
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        navigationController?.setNavigationBarHidden(false, animated: true)
    }
    
    // MARK: - Private Methods
    
    /// Configure basic view properties
    private func configureView() {
        view.backgroundColor = .systemBackground
        navigationController?.setNavigationBarHidden(true, animated: false)
    }
    
    /// Set up view hierarchy and constraints
    private func setupLayout() {
        // Add subviews to the view hierarchy
        [headerView, messageListView, composerView].forEach { view.addSubview($0) }
        
        // Set up constraints
        NSLayoutConstraint.activate([
            // Header view constraints
            headerView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            headerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            headerView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            headerView.heightAnchor.constraint(equalToConstant: 50),
            
            // Message list view constraints
            messageListView.topAnchor.constraint(equalTo: headerView.bottomAnchor),
            messageListView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            messageListView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            messageListView.bottomAnchor.constraint(equalTo: composerView.topAnchor),
            
            // Composer view constraints
            composerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            composerView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            composerView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
        ])
    }
}
```

***

## **Next Steps**

### **Enhance the User Experience**

* **[Advanced Customizations](/ui-kit/ios/theme-introduction)** – Personalize the chat UI to align with your brand.

***
