Migration Guides
Migration to 5.0.0
CocoaPods setup
The pod name changed to ChatCenterUI, version 5.0.0.
ChatCenterUI configuration
In this version the SDK API is incompatible with 4.x. See the demo app for a setup example.
The main steps remain the same:
-
Configure the server connection:
let chatTransportConfig = ChatTransportConfig(rest: "restURL",
webSocket: "webSocketURL",
dataStore: "dataStoreURL") -
Configure network options:
var chatNetworkConfig = ChatNetworkConfig()
chatNetworkConfig.sslPinning.allowUntrustedSSLCertificate = true -
Configure chat options:
var chatConfig = ChatConfig(transportConfig: chatTransportConfig,
networkConfig: chatNetworkConfig)
chatConfig.searchEnabled = true
chatConfig.voiceRecordingEnabled = true
chatConfig.linkPreviewEnabled = true
chatConfig.keepSocketActive = true -
Initialize the SDK:
let chatCenterSDK = ChatCenterUISDK(providerUid: "YOUR_PROVIDER_UID",
chatConfig: chatConfig,
loggerConfig: ChatLoggerConfig(logLevel: .all)) -
Configure themes:
chatCenterSDK.theme = makeLightTheme()
chatCenterSDK.darkTheme = makeDarkTheme()
Appearance configuration
Appearance is configured through themes (light and dark). The SDK provides three customization levels:
- Minimal — configure colors, fonts, and/or images (for example, to match corporate colors).
- Component-based — configure SDK design system components (reusable elements, such as buttons).
- Precise — detailed flow configuration (chat or search screens) for tuning the appearance of specific elements on a screen.
The levels have a nested structure:
let components = ChatComponents(images: ChatImages(), colors: ChatColors(), typography: ChatTypography())
let theme = ChatTheme(components: components)
// theme.flows is available for detailed flow configuration
Lower levels have higher priority: a value set in ChatFlow overrides a value from ChatColors.
Migration to 5.3.0
In 5.3, design system types and properties were renamed to a unified style. After 5.3, only backward-compatible changes are added in minor releases.
What changed:
- 15 types are preserved as
@available(*, deprecated)typealiases — old code still compiles with a warning. For 14 of the 15 aliases the attribute does not includerenamed:, so Fix-It will not suggest a replacement. ForSystemMessagesStyles → ChatSystemMessagesStylesFix-It works. - Some properties were renamed for consistency (suffixes such as
Color,Style, etc. were added). Xcode shows a warning, but Fix-It does not work.
Rename the old names manually according to the table below.
Renamed types (deprecated aliases)
Old names are preserved as aliases and marked @available(*, deprecated). They will be removed in the next major release.
| Old name (deprecated) | Current name |
|---|---|
AudioMessageStyle | AudioChatMessageStyle |
AudioPlayerChatStyle | AudioPlayerStyle |
ButtonChatStyle | ButtonStyle |
FileMessageStyle | FileChatMessageStyle |
IconButtonChatStyle | IconButtonStyle |
ImageMessageStyle | ImageChatMessageStyle |
InputChatTextStyle | ChatInputTextStyle |
InputChatVoiceStyle | ChatInputVoiceStyle |
InputViewStyle | ChatInputStyle |
PhotoPickerStyle | ChatMenuStyle (see note below) |
PlaceholderChatStyle | ChatPlaceholderStyle |
SearchBarChatStyle | SearchBarStyle |
SystemMessagesStyles | ChatSystemMessagesStyles |
TextChatStyle | ChatTextStyle |
TextMessageStyle | TextChatMessageStyle |
See also Known issues.
The structure of individual styles changed — for example, voice messages (ChatInputVoiceStyle). Check your code against the current style API.
A static build method was added for creating styles — it creates a style and configures it via a closure:
// Build design system components
let components = ChatComponents.build { components in
components.searchBarStyle.cancelButtonStyle.color.normal = .black
components.loadingChatStyle.indicatorStyle.backgroundColor = .systemGray3
components.loadingChatStyle.indicatorStyle.cornerRadius = 20.0
components.audioPlayerStyle.playButtonStyle.image = ChatImage(system: "play.fill", tintColor: .red)
components.audioPlayerStyle.pauseButtonStyle.image = ChatImage(system: "pause.fill", tintColor: .green)
components.audioPlayerStyle.progressViewStyle.color = .black
components.audioPlayerStyle.progressViewStyle.backgroundColor = .yellow
}
The apply method mutates properties of an existing style via a closure — without an intermediate variable:
// Apply settings for the search screen
theme.flows.searchFlow.apply {
$0.navigationBarStyle = NavigationBarStyle.build(with: components, configure: {
$0.hidden = false
})
$0.searchMessageStyle.apply {
$0.matchTextStyle = .init(font: UIFont.systemFont(ofSize: 20), color: .systemGreen)
$0.nextImage = ChatImage(system: "chevron.forward", tintColor: .systemGreen)
}
$0.navigationBarStyle.searchBarStyle.cancelButtonStyle.color.normal = .red
$0.notFoundTextStyle = ChatTextStyle(font: typography.message, color: .red)
}
apply limitation for shared componentsApplying apply to components from ChatComponents via a flow changes them globally across the whole theme. To change a component only in one flow, create a separate instance and assign it locally.
Migration to 5.4.0
New public APIs
- Added
OpenGraphViewStylefor styling OpenGraph link previews inside messages. Configured viatheme.flows.chatFlow.outcomeMessages.textMessageStyle.openGraphStyle(outgoing) andtheme.flows.chatFlow.incomeMessages.textMessageStyle.openGraphStyle(incoming). - Added the
chatCenterUI(chatCenter:didLog:)method toChatCenterUISDKDelegate. If a delegate is set, the SDK forwards its logs to it — useful for piping into Sentry, Datadog, or an external logger. All delegate methods have empty default implementations, so implementingdidLogis optional. - Added the
ChatConfig.shouldUseRemoteConfigparameter (defaulttrue). Whenfalse, the SDK uses only local values forkeepSocketActive,keepSocketActiveDuringOperatorSession, and others — the server-sidechannelConfigis ignored. Set tofalseif you want to guarantee local settings are used.
Compatibility
No external breaking changes — upgrading from 5.3.x is source-compatible.
Migration to 5.5.0
New public APIs
- Added the
QuoteStyle.backgroundCornerRadius: CGFloatproperty — corner radius of the quote background.
Fixes
- Fixed style application on dynamic theme switching (previously some elements could keep old colors).
- Fixed opening files sent by the operator.
- Fixed the message mask for messages with images.
Compatibility
No external breaking changes — upgrading from 5.4.x is source-compatible.
Migration to 5.6.0
New methods
Prefilling the input field
Added the prefill(message:) method to insert text into the input field before opening the chat:
chatCenterSDK.prefill(message: "Question about order #12345")
do {
let chatController = try chatCenterSDK.getChat()
// the text will be in the input field
} catch {
// see getting-started/open_chat.md
}
The text is inserted once on the next getChat() call, then reset.
Design system changes
Scroll-to-bottom button
ScrollToMessageButtonStyle gained the alwaysShow: Bool property (default false). When true, the scroll-to-bottom button is shown at all times, including when there are no unread messages:
let chatFlow = theme.flows.chatFlow
chatFlow.scrollToBottomUnreadMessagesButtonStyle.alwaysShow = true
Survey button style
The questionBackgroundColor property in SurveyChatMessageStyle is marked as deprecated. Use questionButtonColor instead, which supports normal/highlighted/disabled states:
let surveyStyle = theme.flows.chatFlow.systemMessages.surveyMessageStyle
surveyStyle.questionButtonColor.normal = .systemGreen
surveyStyle.questionButtonColor.highlighted = .systemGreen.withAlphaComponent(0.7)
surveyStyle.questionButtonColor.disabled = .systemGray
Updated surveys
The survey UI has been reworked. No integrator-side configuration is required — changes are applied automatically:
- The input field is blocked while a survey is active.
- Survey buttons now highlight on tap.
- Server-controlled behavior: comment field (threshold via the
clientCommentThresholdpayload), automatic survey hide (hideAfter), submitting all answers as one message on.api21+. These parameters are not exposed in the public SDK API — configure them via edna.
Message length limit
The input field now limits message length to 4000 characters at the UI level (previously the limit was applied only on send). Pasting text that exceeds the limit is truncated automatically.
Migration to 5.7.0
Updating user data after authorization
ChatUser gained the updateData(data:) method — it updates user data without calling authorize again:
var chatUser = ChatUser(identifier: "user_uuid", name: "Ivan Ivanov")
chatCenterSDK.authorize(user: chatUser)
// Later — when additional data is ready
chatUser.updateData(data: ["email": "ivan@example.ru", "segment": "vip"])
The update is sent to the server on the next viewDidAppear of the chat screen.
authorizeThe method is mutating — the ChatUser variable must be var. Call updateData on the same chatUser you passed to authorize(user:). If you reassign chatUser = ChatUser(...) and call updateData on the new value, the SDK will not see the update.
Fixes
- Fixed quick replies not being cleared when the display mode changes (inline/toolbar).
- Fixed visibility of the search button in the navigation bar when both the keyboard button and search are enabled at the same time.
Migration to 5.8.0 / 5.8.1 / 5.8.2
No external breaking changes. Upgrading from 5.7.x is source-compatible. Details — in the changelog:
- 5.8.0 — no public API changes, internal improvements.
- 5.8.1 — fix for a race condition when updating user data before the WebSocket connection is established.
- 5.8.2 — fix for the WebSocket disconnecting when the chat is opened from a push notification; documentation refinements.
Notes that apply to all 5.x versions
ChatLogLevel is an OptionSet, not an enum
ChatLogLevel is public struct ChatLogLevel: OptionSet. Implications:
- Valid values:
.off,.info,.rest,.webSocket,.userInterface,.error,.network,.all. - Values can be combined via an array literal:
[.info, .error]→ only info and error. switch logLevel { case .all: ... }does not work — uselogLevel.contains(.error)for checks.
// Correct
let logger = ChatLoggerConfig(logLevel: [.info, .error])
if logger.logLevel.contains(.network) {
// ...
}
If old code used ChatLogLevel as an enum (switch/case .all), rewrite it using contains(...).
ChatConfig — deprecated properties
The properties searchEnabled, voiceRecordingEnabled, linkPreviewEnabled, keepSocketActive, keepSocketActiveDuringOperatorSession, scrollToLatest, historyLoadingCount, showAttachButton, surveyCompletionDelay are duplicated by the server-side channelConfig. By default (shouldUseRemoteConfig = true) server values override local ones. See SDK options for details.
These properties are marked deprecated only in doc comments, without the @available attribute. Xcode will not show a strikethrough or Fix-It — rely on the list above and the table in chat_config.md.