# 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:

```swift
@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()
}
```

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:

```swift
class CustomMessageResolver: MessageTypeResolving {

    func hasCustomAttachment(message: ChatMessage) -> Bool {
        message.extraData["ai_generated"] == true
    }
}
```

Finally, you need to inject this resolver when initializing the SDK:

```swift
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`:

```swift
func makeMessageListContainerModifier() -> some ViewModifier {
    CustomMessageListContainerModifier(typingIndicatorHandler: typingIndicatorHandler)
}
```

Where the `CustomMessageListContainerModifier` would look something like this:

```swift
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](https://github.com/GetStream/chat-ai-samples/blob/main/ios/AIComponents/TypingIndicatorHandler.swift).


---

This page was last updated at 2026-04-17T17:33:38.679Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/ios/v4/ai-integrations/swiftui-integration/](https://getstream.io/chat/docs/sdk/ios/v4/ai-integrations/swiftui-integration/).