Skip to main content
Version: 5.9.0

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:

  1. Configure the server connection:

    let chatTransportConfig = ChatTransportConfig(rest: "restURL",
    webSocket: "webSocketURL",
    dataStore: "dataStoreURL")
  2. Configure network options:

    var chatNetworkConfig = ChatNetworkConfig()
    chatNetworkConfig.sslPinning.allowUntrustedSSLCertificate = true
  3. Configure chat options:

    var chatConfig = ChatConfig(transportConfig: chatTransportConfig,
    networkConfig: chatNetworkConfig)
    chatConfig.searchEnabled = true
    chatConfig.voiceRecordingEnabled = true
    chatConfig.linkPreviewEnabled = true
    chatConfig.keepSocketActive = true
  4. Initialize the SDK:

    let chatCenterSDK = ChatCenterUISDK(providerUid: "YOUR_PROVIDER_UID",
    chatConfig: chatConfig,
    loggerConfig: ChatLoggerConfig(logLevel: .all))
  5. Configure themes:

    chatCenterSDK.theme = makeLightTheme()
    chatCenterSDK.darkTheme = makeDarkTheme()

Appearance configuration

Appearance is configured through themes (light and dark). The SDK provides three customization levels:

  1. Minimal — configure colors, fonts, and/or images (for example, to match corporate colors).
  2. Component-based — configure SDK design system components (reusable elements, such as buttons).
  3. 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 include renamed:, so Fix-It will not suggest a replacement. For SystemMessagesStyles → ChatSystemMessagesStyles Fix-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
AudioMessageStyleAudioChatMessageStyle
AudioPlayerChatStyleAudioPlayerStyle
ButtonChatStyleButtonStyle
FileMessageStyleFileChatMessageStyle
IconButtonChatStyleIconButtonStyle
ImageMessageStyleImageChatMessageStyle
InputChatTextStyleChatInputTextStyle
InputChatVoiceStyleChatInputVoiceStyle
InputViewStyleChatInputStyle
PhotoPickerStyleChatMenuStyle (see note below)
PlaceholderChatStyleChatPlaceholderStyle
SearchBarChatStyleSearchBarStyle
SystemMessagesStylesChatSystemMessagesStyles
TextChatStyleChatTextStyle
TextMessageStyleTextChatMessageStyle

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 components

Applying 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 OpenGraphViewStyle for styling OpenGraph link previews inside messages. Configured via theme.flows.chatFlow.outcomeMessages.textMessageStyle.openGraphStyle (outgoing) and theme.flows.chatFlow.incomeMessages.textMessageStyle.openGraphStyle (incoming).
  • Added the chatCenterUI(chatCenter:didLog:) method to ChatCenterUISDKDelegate. 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 implementing didLog is optional.
  • Added the ChatConfig.shouldUseRemoteConfig parameter (default true). When false, the SDK uses only local values for keepSocketActive, keepSocketActiveDuringOperatorSession, and others — the server-side channelConfig is ignored. Set to false if 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: CGFloat property — 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 clientCommentThreshold payload), 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.

Use the same variable that you passed to authorize

The 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 — use logLevel.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.

Xcode will not show a warning

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.