UI components

Nabla iOS Messaging UI components

📘

This guide assumes that you want to use Nabla's built-in UI components to build your messaging experience. If you're only interested in getting the data and building your own UI, check out the Core module.

The NablaMessagingUI library is compatible with iOS 13 and higher, but some features will only be available from iOS 14 and higher:

  • selecting multiple images at once from the library.
  • uploading document from the Files app on patients' phone.

Conversations list

Once the patient is authenticated in your app, you can access their conversations and display them. Be sure to import NablaMessagingUI for Xcode to find the definition of NablaViewFactory.

To display the list of conversations your patient is a part of, the Nabla SDK provides a NablaViewFactory.createConversationListView method that returns a ConversationListView.

Simply include it in your view or view controller:

Preview of the conversations list UI component

import UIKit
import NablaCore
import NablaMessagingCore
import NablaMessagingUI

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let conversationListView = NablaClient.shared.messaging.views.createConversationListView(delegate: self)
        conversationListView.frame = view.bounds // For sample purposes, you should probably use AutoLayout instead in your app
        view.addSubview(conversationListView)
    }

}

extension ViewController: ConversationListDelegate {
    func conversationList(didSelect conversation: Conversation) {
        print("User did select \(conversation.id)")
    }
}

ConversationListView encompasses a scrollable list of all conversations, along with UI for loading and error states. The scrolling in the list is wired with a paginated loading of conversations.

Conversations list in the InboxViewController

Preview of the inbox UI component

While ConversationListView provides a higher flexibility and customization, if all you want is an already-wired standalone ViewController containing conversations list, a toolbar and a Start a conversation button, then use createInboxViewController(delegate):

import UIKit
import NablaCore
import NablaMessagingCore
import NablaMessagingUI

class ViewController: UIViewController {

    private func navigateToInbox() {
        let inboxViewController = NablaClient.shared.messaging.views.createInboxViewController(delegate: self)
        navigationController?.pushViewController(inboxViewController, animated: true)
    }

}


extension ViewController: InboxDelegate {
    func inbox(didCreate conversation: Conversation) {
        print("User did create draft conversation: \(conversation.id)")
    }

    func inbox(didSelect conversation: Conversation) {
        print("User did select existing conversation: \(conversation.id)")
    }
}

Conversation screen

Preview of the conversations list UI component

It's up to you to decide what to do when a user taps a conversation by implementing ConversationListDelegate.conversationList(didSelect:) or InboxDelegate.inbox(didCreate:).

Usually, you will want to "open" this conversation by pushing a new screen. Change the implementation of the delegate:

// If using ConversationListDelegate
extension ViewController: ConversationListDelegate {
    func conversationList(didSelect conversation: Conversation) {
        let destination = NablaClient.shared.messaging.views.createConversationViewController(conversation)
        navigationController?.pushViewController(destination, animated: true)
    }
}

// If using InboxDelegate
extension ViewController: InboxDelegate {
    func inbox(didCreate conversation: Conversation) {
        let destination = NablaClient.shared.messaging.views.createConversationViewController(conversation)
        navigationController?.pushViewController(destination, animated: true)
    }

    func inbox(didSelect conversation: Conversation) {
        let destination = NablaClient.shared.messaging.views.createConversationViewController(conversation)
        navigationController?.pushViewController(destination, animated: true)
    }
}

The ConversationViewController contains:

  • The timeline of conversation’s content, i.e. messages, with a pagination mechanism.
  • The composer where to type a new message or send media attachments.
  • A default navigationItem.titleView with the conversation image and title.

This screen allows users to:

  • Receive:
    • A typing indicator
    • Text messages
    • Images messages (and open them fullscreen)
    • Document messages (and open them fullscreen)
    • Voice messages (and play them)
  • Send:
    • A text message
    • An images message
    • A PDF document message (with files already existing on their device)
    • Voice messages (to record with their microphone)
  • Act on messages:
    • Delete (only their own messages)

Using the camera to send photos

In order for users to use the camera to send photo messages, you must fill your info.plist with the key NSCameraUsageDescription, otherwise the option won't show.

Setting up voice messages

In order to make the recording of voice messages work, you must fill your info.plist with the key NSMicrophoneUsageDescription, otherwise a crash might occur.

Create a new conversation

If you want your user to be able to start a new conversation, you can allow to create it into your app directly:

Task {
  do {
    let conversation = try await NablaMessagingClient.shared.startConversation()
    await MainActor.run {
      let destination = NablaClient.shared.messaging.views.createConversationViewController(conversation)
      navigationController.pushViewController(destination, animated: true)
    }
  } catch {
    print("Error \(error)")
  }
}

If you are not familiar with Task and async method, visit or FAQ or visit the official documentation.