var colors = Appearance.ColorPalette()
colors.accentPrimary = .systemPink
colors.navigationBarTintColor = .systemPink
var fonts = Appearance.FontsSwiftUI()
fonts.body = .system(size: 18)
var images = Appearance.Images()
var appearance = Appearance()
appearance.colorPalette = colors
appearance.fontsSwiftUI = fonts
appearance.images = images
let streamChat = StreamChat(chatClient: chatClient, appearance: appearance)Migrating from 4.x to 5.x
Version 5.x of the SwiftUI SDK keeps the overall architecture from 4.x, but it includes several source-breaking API updates in the customization layer. Most migrations are straightforward and fall into these buckets:
Appearancecustomization now goes through mutable properties instead of initializer parameters.- Several SwiftUI-specific helper views were renamed.
ViewFactorymethods now take a single options object instead of many individual parameters.- Several modifier methods moved from
ViewFactoryto the newStylesprotocol. Utilsgained new formatter parameters and dropped a few deprecated ones.supportedMoreChannelActions,supportedMessageActions, andnavigationBarDisplayModemoved to config objects.
If your app mostly uses the default UI components, the upgrade should be limited to dependency updates and a small number of customization fixes.
Please don't hesitate to contact our Support team or open a ticket in our GitHub repository. We'll help you during your migration process and any issues you might face.
Update the SDK Version
First, update your Swift Package Manager or CocoaPods dependency to version 5.x.
Appearance no longer uses parameterized initializers
In v4, many docs and examples initialized Appearance with parameters such as colors, fonts, or images.
In v5, Appearance has a public empty initializer and you customize it by mutating its properties:
Replace usages like these:
let appearance = Appearance(colors: colors)
let appearance = Appearance(colors: colors, fonts: fonts, images: images)with property-based configuration on a mutable Appearance value.
Use Appearance.FontsSwiftUI for SwiftUI font customization
Appearance now exposes both UIKit fonts and SwiftUI fonts:
appearance.fontsfor UIKit font valuesappearance.fontsSwiftUIfor SwiftUI font values
If you are customizing SwiftUI screens, use Appearance.FontsSwiftUI:
var fonts = Appearance.FontsSwiftUI()
fonts.footnoteBold = .footnote
var appearance = Appearance()
appearance.fontsSwiftUI = fontsIf you were previously using Fonts() in SwiftUI snippets, switch those usages to Appearance.FontsSwiftUI().
Replace tintColor customizations with ColorPalette
The SwiftUI SDK reads brand and navigation colors from Appearance.colorPalette.
The most common v4 migration is replacing generic tint configuration with explicit palette values:
var colors = Appearance.ColorPalette()
colors.accentPrimary = .systemPink
colors.navigationBarTintColor = .systemPink
var appearance = Appearance()
appearance.colorPalette = colorsIn custom SwiftUI views, when you need the configured brand color, prefer the palette values:
@Injected(\.colors) private var colors
Text("Create")
.foregroundColor(Color(colors.accentPrimary))channelNamer became channelNameFormatter
Channel name customization changed in v5.
Replace:
let channelNamer: ChatChannelNamer = { channel, currentUserId in
"This is our custom name: \(channel.name ?? "no name")"
}
let utils = Utils(channelNamer: channelNamer)with:
final class CustomChannelNameFormatter: ChannelNameFormatter {
func format(channel: ChatChannel, forCurrentUserId currentUserId: UserId?) -> String? {
"This is our custom name: \(channel.name ?? "no name")"
}
}
let utils = Utils(channelNameFormatter: CustomChannelNameFormatter())If you were using DefaultChatChannelNamer, migrate to DefaultChannelNameFormatter.
Update renamed reusable SwiftUI views
If you built custom UI with the SDK's reusable views, update the renamed view types:
MessageAvatarView->UserAvatarChannelAvatarView->ChannelAvatarTypingIndicatorBottomView->TypingIndicatorView
For example, this v4 code:
MessageAvatarView(
url: user.imageURL,
size: 40
)becomes:
UserAvatar(
user: user,
size: 40
)Note that UserAvatar takes a ChatUser value directly rather than a URL, and size is now a CGFloat instead of CGSize. If you only have a URL (for example in a quoted message context), use the URL-and-initials initializer:
UserAvatar(
url: url,
initials: initials,
size: 40,
indicator: .none
)The showOnlineIndicator: Bool parameter was replaced by an AvatarIndicator enum: .online, .offline, or .none.
And this:
TypingIndicatorBottomView(
users: users,
typingIndicatorString: typingText
)becomes:
TypingIndicatorView(
users: users,
typingText: typingText
)Utils API changes
Several parameters were added, removed, or renamed on the Utils initializer. The Utils class itself is now marked @MainActor.
Removed parameters:
| v4 parameter | Notes |
|---|---|
imageMerger | Removed; avatar merging is handled internally. |
channelAvatarsMerger | Removed; avatar merging is handled internally. |
channelHeaderLoader | Removed. |
channelNamer | Renamed — see channelNameFormatter below. |
Renamed parameter:
| v4 | v5 |
|---|---|
channelNamer: ChatChannelNamer (closure) | channelNameFormatter: any ChannelNameFormatter (protocol) |
New parameters in v5:
| Parameter | Purpose |
|---|---|
markdownFormatter | Provides custom Markdown rendering for message text. |
messageTimestampFormatter | Formats the timestamp shown on individual messages. |
galleryHeaderViewDateFormatter | Formats the date in the media gallery header. |
messageDateSeparatorFormatter | Formats the date separator labels in the message list. |
fileCDN | CDN provider for file attachments. |
messageAttachmentPreviewIconProvider | Provides icons for attachment preview thumbnails. |
messagePreviewFormatter | Formats the message preview text shown in the channel list. |
channelListConfig | Configuration object for the channel list (see below). |
mediaBadgeDurationFormatter | Formats duration badges on audio and video attachments. |
messageRemindersFormatter | Formats message reminder labels (conforms to MessageRemindersFormatter). |
navigationBarDisplayMode, supportedMoreChannelActions, and supportedMessageActions moved to config objects
In v4 these were methods on the ViewFactory protocol. In v5 they are properties on the relevant config objects.
DefaultViewFactory still exposes a compatibility navigationBarDisplayMode() helper on the v5 branch, but the channel list and message list read ChannelListConfig.navigationBarDisplayMode and MessageListConfig.navigationBarDisplayMode. For migrations, move your customization to the config objects.
navigationBarDisplayMode — remove the ViewFactory override and set the property on ChannelListConfig or MessageListConfig instead:
// v4 – ViewFactory override
func navigationBarDisplayMode() -> NavigationBarItem.TitleDisplayMode { .inline }
// v5 – config property
var channelListConfig = ChannelListConfig()
channelListConfig.navigationBarDisplayMode = .inline
var messageListConfig = MessageListConfig()
messageListConfig.navigationBarDisplayMode = .inline
let utils = Utils(channelListConfig: channelListConfig, messageListConfig: messageListConfig)supportedMoreChannelActions — remove the ViewFactory override and supply a closure on ChannelListConfig:
// v4 – ViewFactory override
func supportedMoreChannelActions(
for channel: ChatChannel,
onDismiss: @escaping () -> Void,
onError: @escaping (Error) -> Void
) -> [ChannelAction] { ... }
// v5 – ChannelListConfig closure
var channelListConfig = ChannelListConfig()
channelListConfig.supportedMoreChannelActions = { options in
// options.channel, options.onDismiss, options.onError
return [...]
}supportedMessageActions — remove the ViewFactory override and supply a closure on MessageListConfig:
// v4 – ViewFactory override
func supportedMessageActions(
for message: ChatMessage,
channel: ChatChannel,
onFinish: @escaping (MessageActionInfo) -> Void,
onError: @escaping (Error) -> Void
) -> [MessageAction] { ... }
// v5 – MessageListConfig closure
var messageListConfig = MessageListConfig()
messageListConfig.supportedMessageActions = { options in
// options.message, options.channel, options.onFinish, options.onError
return [...]
}New Styles protocol — modifier customization moved out of ViewFactory
v5 introduces a Styles protocol that owns all ViewModifier-returning customizations. Several methods that were on ViewFactory in v4 now live on Styles instead.
The SDK ships two concrete implementations:
LiquidGlassStyles— uses the iOS 26 Liquid Glass material where available.RegularStyles— the classic appearance for earlier OS versions.
DefaultViewFactory uses LiquidGlassStyles on iOS 26+ and RegularStyles otherwise. To customize modifiers, conform to Styles and assign your implementation to factory.styles:
struct MyStyles: Styles {
// override only what you need
func makeComposerViewModifier(options: ComposerViewModifierOptions) -> some ViewModifier {
MyComposerModifier()
}
}
DefaultViewFactory.shared.styles = MyStyles()For channel list search, this change is behavioral as well as structural. In v5, search is applied through Styles.makeSearchableModifier(options:). makeChannelListTopView(options:) remains available, but it is now just a top content slot and no longer provides searchText or owns the search bar UI.
Methods moved from ViewFactory to Styles:
v4 ViewFactory method | v5 Styles method |
|---|---|
func makeChannelListContentModifier() -> ChannelListContentModifier | func makeChannelListContentModifier(options: ChannelListContentModifierOptions) -> ChannelListContentModifier |
func makeChannelListModifier() -> ChannelListModifier | func makeChannelListModifier(options: ChannelListModifierOptions) -> ChannelListModifier |
func makeMessageListModifier() -> MessageListModifier | func makeMessageListModifier(options: MessageListModifierOptions) -> MessageListModifier |
func makeMessageListContainerModifier() -> MessageListContainerModifier | func makeMessageListContainerModifier(options: MessageListContainerModifierOptions) -> MessageListContainerModifier |
func makeMessageViewModifier(for messageModifierInfo: MessageModifierInfo) -> MessageViewModifier | func makeMessageViewModifier(for messageModifierInfo: MessageModifierInfo) -> MessageViewModifier |
func makeComposerViewModifier() -> ComposerViewModifier | func makeComposerViewModifier(options: ComposerViewModifierOptions) -> ComposerViewModifier |
New Styles methods with no v4 equivalent:
func makeComposerInputViewModifier(options: ComposerInputModifierOptions) -> ComposerInputViewModifierfunc makeComposerButtonViewModifier(options: ComposerButtonModifierOptions) -> ComposerButtonViewModifierfunc makeScrollToBottomButtonModifier(options: ScrollToBottomButtonModifierOptions) -> ScrollToBottomButtonViewModifierfunc makeBouncedMessageActionsModifier(viewModel: ChatChannelViewModel) -> BouncedMessageActionsModifierTypefunc makeSuggestionsContainerModifier(options: SuggestionsContainerModifierOptions) -> SuggestionsContainerModifierfunc makeToolbarConfirmActionModifier(options: ToolbarConfirmActionModifierOptions) -> ToolbarConfirmActionViewModifierfunc makeSearchableModifier(options: SearchableModifierOptions) -> SearchableModifierType
Review your ViewFactory implementations
The biggest ViewFactory change in v5 is that the API moved from many ad-hoc parameters to option objects. If you had a custom factory in v4, you should review every override.
Below is the full mapping validated against the latest develop and v5 branches of stream-chat-swiftui.
Channel List
| v4 | v5 |
|---|---|
func makeChannelListHeaderViewModifier(title: String) -> HeaderViewModifier | func makeChannelListHeaderViewModifier(options: ChannelListHeaderViewModifierOptions) -> HeaderViewModifier |
func makeNoChannelsView() -> NoChannels | func makeNoChannelsView(options: NoChannelsViewOptions) -> NoChannels |
func makeLoadingView() -> LoadingContent | func makeLoadingView(options: LoadingViewOptions) -> LoadingContent |
func makeChannelListItem(channel: ChatChannel, channelName: String, avatar: UIImage, onlineIndicatorShown: Bool, disabled: Bool, selectedChannel: Binding<ChannelSelectionInfo?>, swipedChannelId: Binding<String?>, channelDestination: @escaping (ChannelSelectionInfo) -> ChannelDestination, onItemTap: @escaping (ChatChannel) -> Void, trailingSwipeRightButtonTapped: @escaping (ChatChannel) -> Void, trailingSwipeLeftButtonTapped: @escaping (ChatChannel) -> Void, leadingSwipeButtonTapped: @escaping (ChatChannel) -> Void) -> ChannelListItemType | func makeChannelListItem(options: ChannelListItemOptions<ChannelDestination>) -> ChannelListItemType |
func makeChannelListBackground(colors: ColorPalette) -> ChannelListBackground | func makeChannelListBackground(options: ChannelListBackgroundOptions) -> ChannelListBackground |
func makeChannelListDividerItem() -> ChannelListDividerItem | func makeChannelListDividerItem(options: ChannelListDividerItemOptions) -> ChannelListDividerItem |
func makeMoreChannelActionsView(for channel: ChatChannel, swipedChannelId: Binding<String?>, onDismiss: @escaping () -> Void, onError: @escaping (Error) -> Void) -> MoreActionsView | func makeMoreChannelActionsView(options: MoreChannelActionsViewOptions) -> MoreActionsView |
func makeTrailingSwipeActionsView(channel: ChatChannel, offsetX: CGFloat, buttonWidth: CGFloat, swipedChannelId: Binding<String?>, leftButtonTapped: @escaping (ChatChannel) -> Void, rightButtonTapped: @escaping (ChatChannel) -> Void) -> TrailingSwipeActionsViewType | func makeTrailingSwipeActionsView(options: TrailingSwipeActionsViewOptions) -> TrailingSwipeActionsViewType |
func makeLeadingSwipeActionsView(channel: ChatChannel, offsetX: CGFloat, buttonWidth: CGFloat, swipedChannelId: Binding<String?>, buttonTapped: @escaping (ChatChannel) -> Void) -> LeadingSwipeActionsViewType | func makeLeadingSwipeActionsView(options: LeadingSwipeActionsViewOptions) -> LeadingSwipeActionsViewType |
func makeChannelListTopView(searchText: Binding<String>) -> ChannelListTopViewType | func makeChannelListTopView(options: ChannelListTopViewOptions) -> ChannelListTopViewType (no searchText; search customization moved to Styles.makeSearchableModifier(options:)) |
func makeChannelListFooterView() -> ChannelListFooterViewType | func makeChannelListFooterView(options: ChannelListFooterViewOptions) -> ChannelListFooterViewType |
func makeChannelListStickyFooterView() -> ChannelListStickyFooterViewType | func makeChannelListStickyFooterView(options: ChannelListStickyFooterViewOptions) -> ChannelListStickyFooterViewType |
func makeSearchResultsView(selectedChannel: Binding<ChannelSelectionInfo?>, searchResults: [ChannelSelectionInfo], loadingSearchResults: Bool, onlineIndicatorShown: @escaping (ChatChannel) -> Bool, channelNaming: @escaping (ChatChannel) -> String, imageLoader: @escaping (ChatChannel) -> UIImage, onSearchResultTap: @escaping (ChannelSelectionInfo) -> Void, onItemAppear: @escaping (Int) -> Void) -> ChannelListSearchResultsViewType | func makeSearchResultsView(options: SearchResultsViewOptions) -> ChannelListSearchResultsViewType |
func makeChannelListSearchResultItem(searchResult: ChannelSelectionInfo, onlineIndicatorShown: Bool, channelName: String, avatar: UIImage, onSearchResultTap: @escaping (ChannelSelectionInfo) -> Void, channelDestination: @escaping (ChannelSelectionInfo) -> ChannelDestination) -> ChannelListSearchResultItem | func makeChannelListSearchResultItem(options: ChannelListSearchResultItemOptions<ChannelDestination>) -> ChannelListSearchResultItem |
func makeChannelListContentModifier() -> ChannelListContentModifier | moved to Styles — see the Styles section above |
func makeChannelListModifier() -> ChannelListModifier | moved to Styles — see the Styles section above |
no v4 equivalent | func makeChannelAvatarView(options: ChannelAvatarViewOptions) -> ChannelAvatarViewType |
no v4 equivalent | func makeChannelListItemBackground(options: ChannelListItemBackgroundOptions) -> ChannelListItemBackground |
Channel And Message List
| v4 | v5 |
|---|---|
func makeChannelDestination() -> (ChannelSelectionInfo) -> ChannelDestination | func makeChannelDestination(options: ChannelDestinationOptions) -> @MainActor (ChannelSelectionInfo) -> ChannelDestination |
func makeMessageThreadDestination() -> (ChatChannel, ChatMessage) -> MessageThreadDestination | func makeMessageThreadDestination(options: MessageThreadDestinationOptions) -> @MainActor (ChatChannel, ChatMessage) -> MessageThreadDestination |
func makeEmptyMessagesView(for channel: ChatChannel, colors: ColorPalette) -> EmptyMessagesViewType | func makeEmptyMessagesView(options: EmptyMessagesViewOptions) -> EmptyMessagesViewType |
func makeMessageListModifier() -> MessageListModifier | moved to Styles — see the Styles section above |
func makeMessageListContainerModifier() -> MessageListContainerModifier | moved to Styles — see the Styles section above |
func makeMessageViewModifier(for messageModifierInfo: MessageModifierInfo) -> MessageViewModifier | moved to Styles — see the Styles section above |
func makeMessageAvatarView(for userDisplayInfo: UserDisplayInfo) -> UserAvatar | removed — use func makeUserAvatarView(options: UserAvatarViewOptions) -> UserAvatarViewType |
func makeQuotedMessageAvatarView(for userDisplayInfo: UserDisplayInfo, size: CGSize) -> QuotedUserAvatar | removed — use func makeUserAvatarView(options: UserAvatarViewOptions) -> UserAvatarViewType |
func makeChannelHeaderViewModifier(for channel: ChatChannel) -> ChatHeaderViewModifier | func makeChannelHeaderViewModifier(options: ChannelHeaderViewModifierOptions) -> ChatHeaderViewModifier |
func makeChannelLoadingView() -> ChannelLoadingViewType | func makeChannelLoadingView(options: ChannelLoadingViewOptions) -> ChannelLoadingViewType |
func makeMessageThreadHeaderViewModifier() -> ThreadHeaderViewModifier | func makeMessageThreadHeaderViewModifier(options: MessageThreadHeaderViewModifierOptions) -> ThreadHeaderViewModifier |
func makeMessageListBackground(colors: ColorPalette, isInThread: Bool) -> MessageListBackground | func makeMessageListBackground(options: MessageListBackgroundOptions) -> MessageListBackground |
func makeMessageContainerView(channel: ChatChannel, message: ChatMessage, width: CGFloat?, showsAllInfo: Bool, isInThread: Bool, scrolledId: Binding<String?>, quotedMessage: Binding<ChatMessage?>, onLongPress: @escaping (MessageDisplayInfo) -> Void, isLast: Bool) -> MessageContainerViewType | removed — use func makeMessageItemView(options: MessageItemViewOptions) -> MessageItemViewType |
func makeMessageTextView(for message: ChatMessage, isFirst: Bool, availableWidth: CGFloat, scrolledId: Binding<String?>) -> MessageTextViewType | func makeMessageTextView(options: MessageTextViewOptions) -> MessageTextViewType |
func makeMessageDateView(for message: ChatMessage) -> MessageDateViewType | func makeMessageDateView(options: MessageDateViewOptions) -> MessageDateViewType |
func makeMessageAuthorAndDateView(for message: ChatMessage) -> MessageAuthorAndDateViewType | func makeMessageAuthorAndDateView(options: MessageAuthorAndDateViewOptions) -> MessageAuthorAndDateViewType |
func makeMessageTranslationFooterView(messageViewModel: MessageViewModel) -> MessageTranslationFooterViewType | removed — translated/pinned/reply annotations are now composed by func makeMessageTopView(options: MessageTopViewOptions) -> MessageTopViewType |
func makeLastInGroupHeaderView(for message: ChatMessage) -> LastInGroupHeaderView | func makeLastInGroupHeaderView(options: LastInGroupHeaderViewOptions) -> LastInGroupHeaderView |
func makeImageAttachmentView(...) -> ImageAttachmentViewType | func makeImageAttachmentView(options: ImageAttachmentViewOptions) -> ImageAttachmentViewType |
func makeGiphyAttachmentView(...) -> GiphyAttachmentViewType | func makeGiphyAttachmentView(options: GiphyAttachmentViewOptions) -> GiphyAttachmentViewType |
func makeLinkAttachmentView(...) -> LinkAttachmentViewType | func makeLinkAttachmentView(options: LinkAttachmentViewOptions) -> LinkAttachmentViewType |
func makeFileAttachmentView(...) -> FileAttachmentViewType | func makeFileAttachmentView(options: FileAttachmentViewOptions) -> FileAttachmentViewType |
func makeVideoAttachmentView(...) -> VideoAttachmentViewType | func makeVideoAttachmentView(options: VideoAttachmentViewOptions) -> VideoAttachmentViewType |
func makeGalleryView(...) -> GalleryViewType | func makeMediaViewer(options: MediaViewerOptions) -> MediaViewerType |
func makeGalleryHeaderView(...) -> GalleryHeaderViewType | func makeMediaViewerHeader(options: MediaViewerHeaderOptions) -> MediaViewerHeaderType |
func makeVideoPlayerView(...) -> VideoPlayerViewType | func makeVideoPlayerView(options: VideoPlayerViewOptions) -> VideoPlayerViewType |
func makeVideoPlayerHeaderView(...) -> VideoPlayerHeaderViewType | func makeVideoPlayerHeaderView(options: VideoPlayerHeaderViewOptions) -> VideoPlayerHeaderViewType |
func makeVideoPlayerFooterView(...) -> VideoPlayerFooterViewType | func makeVideoPlayerFooterView(options: VideoPlayerFooterViewOptions) -> VideoPlayerFooterViewType |
func makeDeletedMessageView(...) -> DeletedMessageViewType | func makeDeletedMessageView(options: DeletedMessageViewOptions) -> DeletedMessageViewType |
func makeSystemMessageView(message: ChatMessage) -> SystemMessageViewType | func makeSystemMessageView(options: SystemMessageViewOptions) -> SystemMessageViewType |
func makeEmojiTextView(...) -> EmojiTextViewType | func makeEmojiTextView(options: EmojiTextViewOptions) -> EmojiTextViewType |
func makeVoiceRecordingView(...) -> VoiceRecordingViewType | func makeVoiceRecordingView(options: VoiceRecordingViewOptions) -> VoiceRecordingViewType |
func makeCustomAttachmentViewType(...) -> CustomAttachmentViewType | func makeCustomAttachmentViewType(options: CustomAttachmentViewTypeOptions) -> CustomAttachmentViewType |
func makeScrollToBottomButton(unreadCount: Int, onScrollToBottom: @escaping () -> Void) -> ScrollToBottomButtonType | func makeScrollToBottomButton(options: ScrollToBottomButtonOptions) -> ScrollToBottomButtonType |
func makeDateIndicatorView(dateString: String) -> DateIndicatorViewType | func makeDateIndicatorView(options: DateIndicatorViewOptions) -> DateIndicatorViewType |
func makeMessageListDateIndicator(date: Date) -> MessageListDateIndicatorViewType | func makeMessageListDateIndicator(options: MessageListDateIndicatorViewOptions) -> MessageListDateIndicatorViewType |
func makeTypingIndicatorBottomView(...) -> TypingIndicatorViewType | removed — use makeInlineTypingIndicatorView(options: TypingIndicatorViewOptions) and/or makeSubtitleTypingIndicatorView(options: SubtitleTypingIndicatorViewOptions) |
func makeGiphyBadgeViewType(...) -> GiphyBadgeViewType | func makeGiphyBadgeViewType(options: GiphyBadgeViewTypeOptions) -> GiphyBadgeViewType |
func makeMessageRepliesView(...) -> MessageRepliesViewType | func makeMessageRepliesView(options: MessageRepliesViewOptions) -> MessageRepliesViewType |
func makeMessageRepliesShownInChannelView(...) -> MessageRepliesShownInChannelViewType | removed — migrate reply/thread annotations to makeMessageTopView(options:) and keep reply count customization in makeMessageRepliesView(options:) |
func makeMessageComposerViewType(...) -> MessageComposerViewType | func makeMessageComposerViewType(options: MessageComposerViewTypeOptions) -> MessageComposerViewType |
func makeLeadingComposerView(...) -> LeadingComposerViewType | func makeLeadingComposerView(options: LeadingComposerViewOptions) -> LeadingComposerViewType |
func makeComposerInputView(...) -> ComposerInputViewType | func makeComposerInputView(options: ComposerInputViewOptions) -> ComposerInputViewType |
func makeComposerTextInputView(...) -> ComposerTextInputViewType | func makeComposerTextInputView(options: ComposerTextInputViewOptions) -> ComposerTextInputViewType |
func makeTrailingComposerView(...) -> TrailingComposerViewType | func makeTrailingComposerView(options: TrailingComposerViewOptions) -> TrailingComposerViewType |
func makeComposerViewModifier() -> ComposerViewModifier | moved to Styles — see the Styles section above |
func makeComposerRecordingView(...) -> ComposerRecordingViewType | removed — use func makeComposerVoiceRecordingInputView(options: ComposerVoiceRecordingInputViewOptions) -> ComposerVoiceRecordingInputViewType |
func makeComposerRecordingLockedView(...) -> ComposerRecordingLockedViewType | removed — use func makeComposerVoiceRecordingInputView(options: ComposerVoiceRecordingInputViewOptions) -> ComposerVoiceRecordingInputViewType |
func makeComposerRecordingTipView() -> ComposerRecordingTipViewType | removed — use func makeComposerVoiceRecordingInputView(options: ComposerVoiceRecordingInputViewOptions) -> ComposerVoiceRecordingInputViewType |
func makeAttachmentPickerView(...) -> AttachmentPickerViewType | func makeAttachmentPickerView(options: AttachmentPickerViewOptions) -> AttachmentPickerViewType |
func makeAttachmentSourcePickerView(...) -> AttachmentSourcePickerViewType | removed — use func makeAttachmentTypePickerView(options: AttachmentTypePickerViewOptions) -> AttachmentTypePickerViewType |
func makePhotoAttachmentPickerView(...) -> PhotoAttachmentPickerViewType | removed — use func makeAttachmentMediaPickerView(options: AttachmentMediaPickerViewOptions) -> AttachmentMediaPickerViewType |
func makeFilePickerView(...) -> FilePickerViewType | removed — use func makeAttachmentFilePickerView(options: AttachmentFilePickerViewOptions) -> AttachmentFilePickerViewType |
func makeCameraPickerView(...) -> CameraPickerViewType | removed — use func makeAttachmentCameraPickerView(options: AttachmentCameraPickerViewOptions) -> AttachmentCameraPickerViewType |
func makeCustomAttachmentView(...) -> CustomAttachmentViewType | removed — use func makeCustomAttachmentPickerView(options: CustomAttachmentPickerViewOptions) -> CustomAttachmentPickerViewType |
func makeCustomAttachmentPreviewView(...) -> CustomAttachmentPreviewViewType | func makeCustomAttachmentPreviewView(options: CustomAttachmentPreviewViewOptions) -> CustomAttachmentPreviewViewType |
func makeAssetsAccessPermissionView() -> AssetsAccessPermissionViewType | removed with no direct replacement |
func supportedMessageActions(...) -> [MessageAction] | moved to MessageListConfig.supportedMessageActions closure |
func makeSendInChannelView(...) -> SendInChannelViewType | func makeSendInChannelView(options: SendInChannelViewOptions) -> SendInChannelViewType |
func makeMessageActionsView(...) -> MessageActionsView | func makeMessageActionsView(options: MessageActionsViewOptions) -> MessageActionsViewType |
func makeReactionsUsersView(...) -> ReactionsUsersViewType | removed — use func makeReactionsDetailView(options: ReactionsDetailViewOptions) -> ReactionsDetailViewType |
func makeBottomReactionsView(...) -> BottomReactionsViewType | func makeBottomReactionsView(options: ReactionsBottomViewOptions) -> ReactionsBottomViewType |
func makeMessageReactionView(...) -> MessageReactionViewType | func makeMessageReactionView(options: MessageReactionViewOptions) -> MessageReactionViewType |
func makeReactionsOverlayView(...) -> ReactionsOverlayViewType | func makeReactionsOverlayView(options: ReactionsOverlayViewOptions) -> ReactionsOverlayViewType |
func makeReactionsBackgroundView(...) -> ReactionsBackground | func makeReactionsBackgroundView(options: ReactionsBackgroundOptions) -> ReactionsBackground |
func makeReactionsContentView(...) -> ReactionsContentView | func makeReactionsContentView(options: ReactionsContentViewOptions) -> ReactionsContentView |
no v4 equivalent | func makeMoreReactionsView(options: MoreReactionsViewOptions) -> MoreReactionsViewType |
func makeQuotedMessageHeaderView(...) -> QuotedMessageHeaderViewType | removed — use func makeComposerQuotedMessageView(options: ComposerQuotedMessageViewOptions) -> ComposerQuotedMessageViewType |
func makeQuotedMessageView(...) -> QuotedMessageViewType | func makeQuotedMessageView(options: QuotedMessageViewOptions) -> QuotedMessageViewType |
func makeQuotedMessageContentView(options: QuotedMessageContentViewOptions) -> QuotedMessageContentViewType | removed — customize quoted-message rendering with makeQuotedMessageView(options:) and makeChatQuotedMessageView(options:) |
no v4 equivalent | func makeChatQuotedMessageView(options: ChatQuotedMessageViewOptions) -> ChatQuotedMessageViewType |
func makeCustomAttachmentQuotedView(for message: ChatMessage) -> CustomAttachmentQuotedViewType | removed with no direct replacement |
func makeEditedMessageHeaderView(...) -> EditedMessageHeaderViewType | removed — use func makeComposerEditedMessageView(options: ComposerEditedMessageViewOptions) -> ComposerEditedMessageViewType |
func makeCommandsContainerView(...) -> CommandsContainerViewType | removed — use func makeSuggestionsContainerView(options: SuggestionsContainerViewOptions) -> SuggestionsContainerViewType |
func makeMessageReadIndicatorView(...) -> MessageReadIndicatorViewType | func makeMessageReadIndicatorView(options: MessageReadIndicatorViewOptions) -> MessageReadIndicatorViewType |
func makeNewMessagesIndicatorView(...) -> NewMessagesIndicatorViewType | func makeNewMessagesIndicatorView(options: NewMessagesIndicatorViewOptions) -> NewMessagesIndicatorViewType |
func makeJumpToUnreadButton(...) -> JumpToUnreadButtonType | func makeJumpToUnreadButton(options: JumpToUnreadButtonOptions) -> JumpToUnreadButtonType |
func navigationBarDisplayMode() -> NavigationBarItem.TitleDisplayMode | moved to ChannelListConfig and MessageListConfig — see section above |
no v4 equivalent | func makeUserAvatarView(options: UserAvatarViewOptions) -> UserAvatarViewType |
no v4 equivalent | func makeChannelBarsVisibilityViewModifier(options: ChannelBarsVisibilityViewModifierOptions) -> ChangeBarsVisibilityModifier |
no v4 equivalent | func makeMessageAttachmentsView(options: MessageAttachmentsViewOptions) -> MessageAttachmentsViewType |
no v4 equivalent | func makeInlineTypingIndicatorView(options: TypingIndicatorViewOptions) -> InlineTypingIndicatorViewType |
no v4 equivalent | func makeSubtitleTypingIndicatorView(options: SubtitleTypingIndicatorViewOptions) -> SubtitleTypingIndicatorViewType |
no v4 equivalent | func makeSendMessageButton(options: SendMessageButtonOptions) -> SendMessageButtonType |
no v4 equivalent | func makeConfirmEditButton(options: ConfirmEditButtonOptions) -> ConfirmEditButtonType |
no v4 equivalent | func makeComposerInputTrailingView(options: ComposerInputTrailingViewOptions) -> ComposerInputTrailingViewType |
no v4 equivalent | func makeComposerVoiceRecordingInputView(options: ComposerVoiceRecordingInputViewOptions) -> ComposerVoiceRecordingInputViewType |
no v4 equivalent | func makeAttachmentCommandsPickerView(options: AttachmentCommandsPickerViewOptions) -> AttachmentCommandsPickerViewType |
no v4 equivalent | func makeAttachmentTypePickerView(options: AttachmentTypePickerViewOptions) -> AttachmentTypePickerViewType |
no v4 equivalent | func makeAttachmentMediaPickerView(options: AttachmentMediaPickerViewOptions) -> AttachmentMediaPickerViewType |
no v4 equivalent | func makeAttachmentFilePickerView(options: AttachmentFilePickerViewOptions) -> AttachmentFilePickerViewType |
no v4 equivalent | func makeAttachmentCameraPickerView(options: AttachmentCameraPickerViewOptions) -> AttachmentCameraPickerViewType |
no v4 equivalent | func makeCustomAttachmentPickerView(options: CustomAttachmentPickerViewOptions) -> CustomAttachmentPickerViewType |
no v4 equivalent | func makeAttachmentPollPickerView(options: AttachmentPollPickerViewOptions) -> AttachmentPollPickerViewType |
no v4 equivalent | func makeReactionsDetailView(options: ReactionsDetailViewOptions) -> ReactionsDetailViewType |
no v4 equivalent | func makeComposerQuotedMessageView(options: ComposerQuotedMessageViewOptions) -> ComposerQuotedMessageViewType |
no v4 equivalent | func makeComposerEditedMessageView(options: ComposerEditedMessageViewOptions) -> ComposerEditedMessageViewType |
no v4 equivalent | func makeMessageAttachmentPreviewThumbnailView(options: MessageAttachmentPreviewViewOptions) -> MessageAttachmentPreviewViewType |
no v4 equivalent | func makeMessageAttachmentPreviewIconView(options: MessageAttachmentPreviewIconViewOptions) -> MessageAttachmentPreviewIconViewType |
no v4 equivalent | func makeSuggestionsContainerView(options: SuggestionsContainerViewOptions) -> SuggestionsContainerViewType |
Polls
| v4 | v5 |
|---|---|
func makeComposerPollView(channelController: ChatChannelController, messageController: ChatMessageController?) -> ComposerPollViewType | func makeComposerPollView(options: ComposerPollViewOptions) -> ComposerPollViewType |
func makePollView(message: ChatMessage, poll: Poll, isFirst: Bool) -> PollViewType | func makePollView(options: PollViewOptions) -> PollViewType |
Thread List
| v4 | v5 |
|---|---|
func makeThreadDestination() -> (ChatThread) -> ThreadDestination | func makeThreadDestination(options: ThreadDestinationOptions) -> @MainActor (ChatThread) -> ThreadDestination |
func makeThreadListItem(thread: ChatThread, threadDestination: @escaping (ChatThread) -> ThreadDestination, selectedThread: Binding<ThreadSelectionInfo?>) -> ThreadListItemType | func makeThreadListItem(options: ThreadListItemOptions<ThreadDestination>) -> ThreadListItemType |
func makeNoThreadsView() -> NoThreads | func makeNoThreadsView(options: NoThreadsViewOptions) -> NoThreads |
func makeThreadsListErrorBannerView(onRefreshAction: @escaping () -> Void) -> ThreadListErrorBannerView | removed in v5 |
func makeThreadListLoadingView() -> ThreadListLoadingView | func makeThreadListLoadingView(options: ThreadListLoadingViewOptions) -> ThreadListLoadingView |
func makeThreadListContainerViewModifier(viewModel: ChatThreadListViewModel) -> ThreadListContainerModifier | func makeThreadListContainerViewModifier(options: ThreadListContainerModifierOptions) -> ThreadListContainerModifier |
func makeThreadListHeaderViewModifier(title: String) -> ThreadListHeaderViewModifier | func makeThreadListHeaderViewModifier(options: ThreadListHeaderViewModifierOptions) -> ThreadListHeaderViewModifier |
func makeThreadListHeaderView(viewModel: ChatThreadListViewModel) -> ThreadListHeaderView | func makeThreadListHeaderView(options: ThreadListHeaderViewOptions) -> ThreadListHeaderView |
func makeThreadListFooterView(viewModel: ChatThreadListViewModel) -> ThreadListFooterView | func makeThreadListFooterView(options: ThreadListFooterViewOptions) -> ThreadListFooterView |
func makeThreadListBackground(colors: ColorPalette) -> ThreadListBackground | func makeThreadListBackground(options: ThreadListBackgroundOptions) -> ThreadListBackground |
func makeThreadListItemBackground(thread: ChatThread, isSelected: Bool) -> ThreadListItemBackground | func makeThreadListItemBackground(options: ThreadListItemBackgroundOptions) -> ThreadListItemBackground |
func makeThreadListDividerItem() -> ThreadListDividerItem | func makeThreadListDividerItem(options: ThreadListDividerItemOptions) -> ThreadListDividerItem |
Add Users And Text Rendering
| v4 | v5 |
|---|---|
func makeAddUsersView(options: AddUsersOptions, onUserTap: @escaping (ChatUser) -> Void) -> AddUsersViewType | func makeAddUsersView(options: AddUsersViewOptions) -> AddUsersViewType |
func makeAttachmentTextView(options: AttachmentTextViewOptions) -> AttachmentTextViewType | func makeAttachmentTextView(options: AttachmentTextViewOptions) -> AttachmentTextViewType |
no v4 equivalent | func makeStreamTextView(options: StreamTextViewOptions) -> StreamTextViewType |
The safest migration path is to take your custom ViewFactory, compile against v5, and then convert each failing override to the new signature shown above.
Migration Checklist
- Update your dependency to
5.x. - Replace
Appearance(...)initializers withvar appearance = Appearance()and property assignment. - Use
Appearance.FontsSwiftUI()for SwiftUI font customization. - Move tint customizations to
ColorPalette, usuallyaccentPrimaryandnavigationBarTintColor. - Rename
channelNamertochannelNameFormatterin yourUtilsinitializer. - Replace
ChatChannelNamerclosure type with a class conforming toChannelNameFormatter. - Replace
DefaultChatChannelNamerwithDefaultChannelNameFormatter. - Remove
imageMerger,channelAvatarsMerger, andchannelHeaderLoaderfrom yourUtilsinitializer. - Replace renamed reusable views:
UserAvatar,ChannelAvatar, andTypingIndicatorView. - Update
UserAvatarcall sites: pass aChatUser(or use the URL+initials initializer), useCGFloatfor size, and switchshowOnlineIndicator: Boolto theAvatarIndicatorenum. - Migrate message container customizations from
makeMessageContainerView(...)tomakeMessageItemView(options:). - Migrate message translation/reply annotation customizations from
makeMessageTranslationFooterView(...)andmakeMessageRepliesShownInChannelView(...)tomakeMessageTopView(options:)andmakeMessageRepliesView(options:). - Migrate gallery/media customizations from
makeGalleryView(...)andmakeGalleryHeaderView(...)tomakeMediaViewer(options:)andmakeMediaViewerHeader(options:). - Keep video player customizations, but update them to the new options-based
makeVideoPlayerView/HeaderView/FooterViewsignatures. - Migrate quoted-message content customization from
makeQuotedMessageContentView(...)tomakeQuotedMessageView(options:)and/ormakeChatQuotedMessageView(options:). - Move
ViewFactorymodifier overrides (makeChannelListContentModifier,makeChannelListModifier,makeMessageListModifier,makeMessageListContainerModifier,makeMessageViewModifier,makeComposerViewModifier) to a customStylesimplementation and assign it tofactory.styles. - If you customized channel-list search in
v4, move that work out ofmakeChannelListTopView(...)and intoStyles.makeSearchableModifier(options:). TreatmakeChannelListTopView(options:)as a separate top content area inv5. - Move
supportedMoreChannelActionstoChannelListConfig.supportedMoreChannelActions. - Move
supportedMessageActionstoMessageListConfig.supportedMessageActions. - Move
navigationBarDisplayModetoChannelListConfig.navigationBarDisplayModeand/orMessageListConfig.navigationBarDisplayMode; do not rely on the compatibility helper onDefaultViewFactory. - Update all
ViewFactoryoverrides that take individual parameters to use the new single options object signature. - Replace removed
ViewFactorymethods with theirv5equivalents (see the Channel And Message List table above).
After these changes, most v4 SwiftUI integrations should compile against v5 without further structural changes.
- Update the SDK Version
- Appearance no longer uses parameterized initializers
- Use Appearance.FontsSwiftUI for SwiftUI font customization
- Replace tintColor customizations with ColorPalette
- channelNamer became channelNameFormatter
- Update renamed reusable SwiftUI views
- Utils API changes
- navigationBarDisplayMode, supportedMoreChannelActions, and supportedMessageActions moved to config objects
- New Styles protocol — modifier customization moved out of ViewFactory
- Review your ViewFactory implementations
- Migration Checklist