@ViewBuilder
func makeCustomAttachmentViewType(
for message: ChatMessage,
isFirst: Bool,
availableWidth: CGFloat,
scrolledId: Binding<String?>
) -> some View {
let isGenerating = message.extraData["generating"]?.boolValue == true
StreamingMessageView(
content: message.text,
isGenerating: isGenerating
)
.padding()
}SwiftUI Integration
The AI components work seamlessly with the StreamChatSwiftUI SDK.
Streaming Message View
You can easily integrate the message streaming view into the StreamChatSwiftUI SDK.
One option is to add it as a custom attachment:
Then, you need to create your own message resolver that will tell the SDK to treat the messages with “ai_generated” custom data as custom attachments:
class CustomMessageResolver: MessageTypeResolving {
func hasCustomAttachment(message: ChatMessage) -> Bool {
message.extraData["ai_generated"] == true
}
}Finally, you need to inject this resolver when initializing the SDK:
let utils = Utils(messageTypeResolver: CustomMessageResolver())
let streamChat = StreamChat(chatClient: chatClient, utils: utils)You can also add thinking indicators, for example at the bottom of the message list, using the makeMessageListContainerModifier:
func makeMessageListContainerModifier() -> some ViewModifier {
CustomMessageListContainerModifier(typingIndicatorHandler: typingIndicatorHandler)
}Where the CustomMessageListContainerModifier would look something like this:
struct CustomMessageListContainerModifier: ViewModifier {
@ObservedObject var typingIndicatorHandler: TypingIndicatorHandler
func body(content: Content) -> some View {
content.overlay {
AIAgentOverlayView(typingIndicatorHandler: typingIndicatorHandler)
}
}
}
struct AIAgentOverlayView: View {
@ObservedObject var typingIndicatorHandler: TypingIndicatorHandler
var body: some View {
VStack {
Spacer()
if typingIndicatorHandler.typingIndicatorShown {
HStack {
AITypingIndicatorView(text: typingIndicatorHandler.state)
Spacer()
}
.padding()
.frame(height: 60)
.background(Color(UIColor.secondarySystemBackground))
}
}
}
}The TypingIndicatorHandler can be an observable object that listens to the different events for the thinking state. For a reference implementation, please check our demo app.