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:

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
InboxViewController

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

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.
Updated 6 months ago