Introduction
The ShortCutFormatter class extends the CometChatTextFormatter class to provide a mechanism for handling shortcuts within messages. This guide walks you through the process of using ShortCutFormatter to implement shortcut extensions in your CometChat application.
Setup
Define the ShortCutFormatter class by extending the CometChatTextFormatter class:
class ShortcutFormatter: CometChatTextFormatter {
// Store fetched shortcuts from the extension
private var messageShortcuts: [String: String] = [:]
// Store suggestion items for display
private var shortcuts: [CometChatUIKitSwift.SuggestionItem] = []
}
2. Initialize with Tracking Character
Set the trackingCharacter to '!' in the initializer:
override init(trackingCharacter: Character) {
super.init(trackingCharacter: "!")
}
3. Define the Regex Pattern
Set the regular expression for shortcut detection in the getRegex() method:
override func getRegex() -> String {
return "(^|\\s)!\\w+"
}
4. Return the Tracking Character
Define the getTrackingCharacter() method to return '!' as the shortcut tracking character:
override func getTrackingCharacter() -> Character {
return "!"
}
5. Implement the Search Method
Override the search() method to search for shortcuts based on the entered query:
override func search(string: String, suggestedItems: (([CometChatUIKitSwift.SuggestionItem]) -> ())? = nil) {
// Fetch shortcuts from extension if not already cached
if messageShortcuts.isEmpty {
CometChat.callExtension(
slug: "message-shortcuts",
type: .get,
endPoint: "v1/fetch",
body: nil
) { [weak self] extensionResponseData in
guard let self = self else { return }
if let shortcutData = extensionResponseData?["shortcuts"] as? [String: String] {
self.messageShortcuts = shortcutData
// Filter shortcuts matching the search string
let suggestedItemsList = self.messageShortcuts
.filter { $0.key.hasPrefix(string) }
.map { CometChatUIKitSwift.SuggestionItem(id: $0.key, name: $0.value, visibleText: $0.value) }
suggestedItems?(suggestedItemsList)
}
} onError: { error in
print("Error occurred while fetching shortcuts: \(error?.errorDescription ?? "Unknown error")")
}
} else {
// Use cached shortcuts
let suggestedItemsList = messageShortcuts
.filter { $0.key.hasPrefix(string) }
.map { CometChatUIKitSwift.SuggestionItem(id: $0.key, name: $0.value, visibleText: $0.value) }
suggestedItems?(suggestedItemsList)
}
}
6. Handle Message String Preparation
Implement the prepareMessageString() method to convert the base chat message into an attributed string for display:
override func prepareMessageString(
baseMessage: BaseMessage,
regexString: String,
alignment: MessageBubbleAlignment = .left,
formattingType: FormattingType
) -> NSAttributedString {
let message = (baseMessage as? TextMessage)?.text ?? ""
return NSAttributedString(string: message)
}
7. Handle Text Tap Events
Override the onTextTapped() method if you need to handle tap events on formatted text:
override func onTextTapped(baseMessage: BaseMessage, tappedText: String, controller: UIViewController?) {
// Handle tap event on shortcut text
}
Complete Implementation
Here’s the complete ShortcutFormatter class:
import Foundation
import CometChatSDK
import CometChatUIKitSwift
class ShortcutFormatter: CometChatTextFormatter {
// MARK: - Properties
private var messageShortcuts: [String: String] = [:]
private var shortcuts: [CometChatUIKitSwift.SuggestionItem] = []
// MARK: - Initialization
override init(trackingCharacter: Character) {
super.init(trackingCharacter: "!")
}
// MARK: - Override Methods
override func getRegex() -> String {
return "(^|\\s)!\\w+"
}
override func getTrackingCharacter() -> Character {
return "!"
}
override func search(string: String, suggestedItems: (([CometChatUIKitSwift.SuggestionItem]) -> ())? = nil) {
if messageShortcuts.isEmpty {
CometChat.callExtension(
slug: "message-shortcuts",
type: .get,
endPoint: "v1/fetch",
body: nil
) { [weak self] extensionResponseData in
guard let self = self else { return }
if let shortcutData = extensionResponseData?["shortcuts"] as? [String: String] {
self.messageShortcuts = shortcutData
let suggestedItemsList = self.messageShortcuts
.filter { $0.key.hasPrefix(string) }
.map { CometChatUIKitSwift.SuggestionItem(id: $0.key, name: $0.value, visibleText: $0.value) }
suggestedItems?(suggestedItemsList)
}
} onError: { error in
print("Error occurred while fetching shortcuts: \(error?.errorDescription ?? "Unknown error")")
}
} else {
let suggestedItemsList = messageShortcuts
.filter { $0.key.hasPrefix(string) }
.map { CometChatUIKitSwift.SuggestionItem(id: $0.key, name: $0.value, visibleText: $0.value) }
suggestedItems?(suggestedItemsList)
}
}
override func prepareMessageString(
baseMessage: BaseMessage,
regexString: String,
alignment: MessageBubbleAlignment = .left,
formattingType: FormattingType
) -> NSAttributedString {
let message = (baseMessage as? TextMessage)?.text ?? ""
return NSAttributedString(string: message)
}
override func onTextTapped(baseMessage: BaseMessage, tappedText: String, controller: UIViewController?) {
// Handle tap event on shortcut text
}
}
Usage
Create an instance of ShortCutFormatter:
let shortcutFormatter = ShortcutFormatter(trackingCharacter: "!")
2. Integrate with Message Composer
If you’re using the CometChatMessageComposer component, integrate the ShortCutFormatter to manage shortcut functionalities:
let shortcutFormatter = ShortcutFormatter(trackingCharacter: "!")
let cometChatMessageComposer = CometChatMessageComposer()
cometChatMessageComposer.set(textFormatter: [shortcutFormatter])
Ensure to pass and present cometChatConversationsWithMessages. If a navigation controller is already in use, utilize the pushViewController function instead of directly presenting the view controller.
Example