The format is based on Keep a Changelog.
ChatMessage.threadParticipants
is now an Array instead of Set #1398- Introduces
ChatChannelVC
and removes responsibilities ofChatMessageListVC
. The latter now is only responsible to render the message list layout, the data is provided byChatChannelVC
orChatThreadVC
. #1314 - Replaces
ChatMessageActionsVC.Delegate
withChatMessageActionsVCDelegate
#1314 - Renames
ChatChannelListRouter.showMessageList()
->showChannel()
#1314 - Removal of
ComposerVCDelegate
#1314 - Replaces
ChatMessageListKeyboardObserver
withComposerKeyboardHandler
#1314
-
ChatChannelVC
:ChatChannelHeaderView
ChatMessageListVC
ComposerVC
-
ChatThreadVC
:ChatThreadHeaderView
ChatMessageListVC
ComposerVC
A new ChatChannelVC
is introduced that represents the old ChatMessageListVC
, which was responsible to display the messages from a channel. The ChatThreadVC
remains the same and it is responsible for displaying the replies in a thread, but now instead of duplicating the implementation from the channel, both use the ChatMessageListVC
and configure it for their needs. For this to be possible the ChatMessageListVC
has now a ChatMessageListVCDataSource
and ChatMessageListVCDelegate
. Both ChatChannelVC
and ChatThreadVC
implement the ChatMessageListVCDataSource
and ChatMessageListVCDelegate
.
- Nuke dependency was updated to v10 #1405
- Fix incorrect RawJSON number handling, the
.integer
case is no longer supported and is replaced by.number
#1375 - Fix message list and thread index out of range issue on
tableView(_:cellForRowAt:)
#1373 - Fix crash when dismissing gallery images #1383
- Improve pagination efficiency #1381
- Fix user mention suggestions not showing all members #1390
- Fix thread avatar view not displaying latest reply author avatar #1398
August 13, 2021
- Fix jumps when presenting message popup actions in a modal #1361
- Fix custom Channel Types not allowing uppercase letters #1361
- Fix
ChatMessageGalleryView.ImagePreview
not compiling in Obj-c #1363 - Fix force unwrap crashes on unknown user roles cases #1365
- Fix "last seen at" representation to use other units other than minutes #1368
- Fix message list dismissing on a modal when scrolling #1364
August 11, 2021
- New
ChannelListSortingKey
sunreadCount
andhasUnread
#1348 - Added
GalleryAttachmentViewInjector.galleryViewAspectRatio
to control the aspect ratio of a gallery inside a message cell #1300
ChatMessageReactionsVC.toggleReaction
is nowopen
#1348- User mentions now fetch suggestions from current channel instead of doing a user search query. Set
Components.mentionAllAppUsers
to true if you want to perform user search instead #1357
- Fix
ChannelListController.synchronize
completion closure not being called when the client is connected #1353 - Selecting suggestions from Composer did not work correctly #1352
- Fixed race condition on
ChatMessageListVC
andChatThreadVC
that causedUITableView
crashes #1347 - Fixed an issue for
ChatThreadVC
opened from a deeplink when new replies are only added to the chat, but not to the replies thread #1354
August 05, 2021
- Extra data is now stored on a hashmap and not using the
ExtraData
generic system ChatMessageLayoutOptionsResolver.optionsForMessage
has a new parameter:appearance
#1304- Renamed
Components.navigationTitleView
->Components.titleContainerView
#1294
The new 4.0
release changes how extraData
is stored and uses a simpler hashmap-based solution. This approach does not require creating type aliases for all generic classes such as ChatClient
.
Example:
client.connectUser(
userInfo: .init(
id: userCredentials.id,
extraData: ["country": .string("NL")]
),
token: token
)
Message
, User
, Channel
, MessageReaction
models now store extraData
in a [String: RawJSON]
container.
let extraData:[String: RawJSON] = .dictionary([
"name": .string(testPayload.name),
"number": .integer(testPayload.number)
])
If you are using ExtraData
from v3
or before 4.0-beta.8
the steps needed to upgrade are the following:
- Remove all type aliases (
typealias ChatUser = _ChatUser<CustomExtraDataTypes.User>
) - Replace all generic types from
StreamChat
andStreamChatUI
classes (__CurrentChatUserController<T>
->CurrentChatUserController
) with the non-generic version - Remove the extra data structs and either use
extraData
directly or (recommended) extend the models - Update your views to read your custom fields from the
extraData
field
Before:
struct Birthland: UserExtraData {
static var defaultValue = Birthland(birthLand: "")
let birthLand: String
}
After:
extension ChatUser {
static let birthLandFieldName = "birthLand"
var birthLand: String {
guard let v = extraData[ChatUser.birthLandFieldName] else {
return ""
}
guard case let .string(birthLand) = v else {
return ""
}
return birthLand
}
}
- Added
ChatChannelHeaderView
UI Component #1294 - Added
ChatThreadHeaderView
UI Component #1294 - Added custom channel events support #1309
- Added
ChatMessageAudioAttachment
, you can access them viaChatMessage.audioAttachments
. There's no UI support as of now, it's in our Roadmap. #1322 - Added message ordering parameter to all
ChannelController
initializers. If you useChatChannelListRouter
it can be done by overriding ashowMessageList
method on it. #1338 - Added support for custom localization of components in framework #1330
- Fix message list header displaying incorrectly the online status for the current user instead of the other one #1294
- Fix deleted last message's appearance on channels list #1318
- Fix reaction bubbles sometimes not being aligned to bubble on short incoming message #1320
- Fix hiding already hidden channels not working #1327
- Fix compilation for Xcode 13 beta 3 where SDK could not compile because of unvailability of
UIApplication.shared
#1333 - Fix member removed from a Channel is still present is MemberListController.members #1323
- Fix composer input field height for long text #1335
- Fix creating direct messaging channels creates CoreData misuse #1337
ContainerStackView
doesn'tassert
when trying to remove a subview, these operations are now no-op #1328ChatClientConfig
'sisLocalStorageEnabled
's default value is nowfalse
/sync
endpoint calls optimized for a setup when local caching is disabled i.e.isLocalStorageEnabled
is set to false.
July 21, 2021
urlRequest(forImage url:)
added toImageCDN
protocol, this can be used to inject custom HTTP headers into image loading requests #1291- Functionality that allows inviting users to channels with subsequent acceptance or rejection on their part #1276
EventsController
which exposes event observing API #1266
- Fix an issue where member role sent from backend was not recognized by the SDK #1288
- Fix crash in
ChannelListUpdater
caused by the lifetime not aligned withChatClient
#1289 - Fix composer allowing sending whitespace only messages #1293
- Fix a crash that would occur on deleting a message #1298
July 19, 2021
- The
ChatSuggestionsViewController
was renamed toChatSuggestionsVC
to follow the same pattern across the codebase. #1195
- Changed Channel from
currentlyTypingMembers: Set<ChatChannelMember>
tocurrentlyTypingUsers: Set<ChatUser>
to show all typing users (not only channel members; eg: watching users) #1254
- Fix deleted messages appearance #1267
- Fix composer commands and attachment buttons not shown in first render when channel is not in cache #1277
- Fix appearance of only-emoji messages #1272
- Fix the appearance of system messages #1281
- Fix a crash happening during MessageList updates #1286
- Support for pasting images into the composer #1258
- The visibility of deleted messages is now configurable using
ChatClientConfig.deletedMessagesVisibility
. You can choose from the following options #1269:
/// All deleted messages are always hidden.
case alwaysHidden
/// Deleted message by current user are visible, other deleted messages are hidden.
case visibleForCurrentUser
/// Deleted messages are always visible.
case alwaysVisible
- Fix crash when scrolling to bottom after sending the first message #1262
- Fix crash when thread root message is not loaded when thread is opened #1263
- Fix issue when messages were changing their sizes when channel is opened #1260
- Fix over fetching previous messages #1110
- Fix an issue where multiple messages in a channel could not quote a single message #1264
- The way attachment view stretches the message cell to fill all available width. Now it's done via
fillAllAvailableWidth
exposed on base attachment injector (set totrue
by default) #1260
July 08, 2021
- Fix issue where badge with unread count could remain visible with 0 value #1259
- Fixed the issue when
ChatClientUpdater.connect
was triggered before the connection was established due to firing.didBecomeActive
notification #1256
July 07, 2021
-
The
ChatSuggestionsViewController
was renamed toChatSuggestionsVC
to follow the rest of the codebase. #1195 -
The
CreateChatChannelButton
component was removed. The component acted only as a placeholder and the functionality should be always provided by the hosting app. For an example implementation see the Demo app. -
The payload of
AnyChatMessageAttachment
changed fromAny
toData
#1248. -
The user setting API was updated. It's now required to call one of the available
connect
methods onChatClient
afterChatClient
's instance is created in order to establish connection and set the current user.If you were doing:
let client = ChatClient(config: config, tokenProvider: .static(token))
Now you should do:
let client = ChatClient(config: config) client.connectUser(userInfo: .init(id: userId), token: token)
Guest users before:
let client = ChatClient( config: config, tokenProvider: .guest( userId: userId, name: userName ) )
Now you should do:
let client = ChatClient(config: config) client.connectGuestUser(userInfo: .init(id: userId))
Anonymous users before:
let client = ChatClient(config: config, tokenProvider: .anonymous)
Now you should do:
let client = ChatClient(config: config) client.connectAnonymousUser()
If you use tokens that expire you probably do something like this:
let client = ChatClient( config: config, tokenProvider: .closure { client, completion in service.fetchToken { token in completion(token) } } )
Now you should do:
let client = ChatClient(config: config) service.fetchToken { token in client.connectUser(userInfo: .init(id: userId), token: token) } // `tokenProvider` property is used to reobtain a new token in case if the current one is expired client.tokenProvider = { completion in service.fetchToken { token in completion(token) } }
search(query:)
function toUserSearchController
to make a custom search with a query #1206queryForMentionSuggestionsSearch(typingMention:)
function toComposerVC
, users can override this function to customize mention search behavior #1206.contains
added toFilter
to be able to filter forteams
#1206
shouldConnectAutomatically
setting inChatConfig
, it now has no effect and all logic that used it now behaves like it was set totrue
.
ConnectionController
fires itscontrollerDidChangeConnectionStatus
method only when the connection status actually changes #1207- Fix cancelled ephemeral (giphy) messages and deleted messages are visible in threads #1238
- Fix crash on missing
cid
value ofMessage
during local cache invalidation #1245 - Messages keep correct order if the local device time is different from the server time #1246
June 23, 2021
ChatOnlineIndicatorView
renamed toOnlineIndicatorView
GalleryContentViewDelegate
methods updated to have optional index pathFileActionContentViewDelegate
methods updated to have optional index pathLinkPreviewViewDelegate
methods updated to have optional index pathscrollToLatestMessageButton
type changed fromUIButton
to_ScrollToLatestMessageButton<ExtraData>
UITableView
is now used instead ofUICollectionView
to display the message list #1219ChatMessageImageGallery
renamed toChatMessageGalleryView
, updated to show any contentImageGalleryVC
renamed toGalleryVC
ImagePreviewable
renamed toGalleryItemPreview
, updated to exposeAttachmentId
onlyGalleryContentViewDelegate
methods are renamed to work not only for image attachment but for anyselectedAttachmentType
removed fromComposerVC
imagePickerVC
renamed tomediaPickerVC
inComposerVC
- Video attachments support:
VideoAttachmentPayload
type is introduced, video attachments are exposed onChatMessage
VideoAttachmentComposerView
component is added to displaying video thumbnails inComposerVC
VideoAttachmentCellView
displaying video previews inChatMessageImageGallery
VideoCollectionViewCell
displaying videos inGalleryVC
VideoPlaybackControlView
used to take actions on the playing video inGalleryVC
VideoPreviewLoader
loading video thumbnails For more information, see #1194mentionText(for:)
function added toComposerVC
for customizing the text displayed for mentions #1188 #1000score
toChatMessageReactionData
so a slack-like reaction view is achievable. This would be used as content inChatMessageReactionsView
#1200- Ability to send silent messages. Silent messages are normal messages with an additional
isSilent
value set totrue
. Silent messages don’t trigger push notification for the recipient.#1211 - Expose
cid
onMessage
#1215 showMediaPicker
/showFilePicker
/attachmentsPickerActions
functions added toComposerVC
so it's possible to customize media/document pickers and add extend action sheet with actions for custom attachment types #1194- Make
ChatThreadVC
show overlay with timestamp of currently visible messages when scrolling #1235 - Expose
layoutOptions
onChatMessageContentView
#1241
scrollToLatestMessageButton
is now visible every time the last message is not visible. Not only when there is unread message. #1208mediaPickerVC
inComposerVC
updated to show both photos and videos #1194ChatMessageListScrollOverlayView
moved outside theChatMessageListView
. Now it's managed byChatMessageListVC
andChatThreadVC
explicitly #1235- Date formatter for scroll overlay used in
ChatMessageListVC
is now exposed asDateFormatter.messageListDateOverlay
#1235
- Fix sorting Member List by
createdAt
causing an issue #1185 - Fix ComposerView not respecting `ChannelConfig.maxMessageLength #1190
- Fix mentions not being parsed correctly #1188
- Fix layout feedback loop for Quoted Message without bubble view #1203
- Fix image/file/link/giphy actions not being handled in
ChatThreadVC
#1207 - Fix
ChatMessageLinkPreviewView
not being taken fromComponents
#1207 - Subviews of
ChatMessageDefaultReactionsBubbleView
are now public #1209 - Fix composer overlapping last message. This happened for channels with typing events disabled. #1210
- Fix an issue where composer textView's caret jumps to the end of input #1117
- Fix deadlock in Controllers when
synchronize
is called in a delegate callback #1214 - Fix restart uploading action not being propagated #1194
- Fix uploading progress not visible on image uploading overlay #1194
- Fix timestamp overlay jumping when more messages are loaded #1235
- Fix flickering of local messages while sending #1241
June 11, 2021
- Due to App Store Connect suddenly starting rejecting builds, we've renamed the following funcs everywhere:
ChannelConfig.commands
is no longer an optional #1182
_ChatChannelListVC.View
is now deprecated. Please useasView
instead #1174
- Add
staysConnectedInBackground
flag toChatClientConfig
#1170 - Add
asView
helper for getting SwiftUI views from StreamChatUI UIViewControllers #1174
- Logic for displaying suggestions (commands or mentions) were not compatible with SwiftUI, so it's changed to AutoLayout #1171
ChatChannelListItemView
now doesn't enable swipe context actions when there are noswipeableViews
for the cell. #1161- Fix websocket connection automatically restored in background #1170
- Commands view in composer is no longer displayed when there are no commands #1171 #1178
ChatMessageContentView
does not add views to main container in reverse order when.flipped
option is included #1125
June 04, 2021
Severity of changes: 🟢 minor
MessageLayoutOption.metadata
was renamed to.timestamp
#1141ComposerVC.showSuggestionsAsChildVC
was renamed toshowSuggestions
#1139- The inner structure of
ChatMessageBubbleView
was updated to match the common component pattern #1118 - The inner structure of
QuotedChatMessageView
was updated to match the common component pattern #1123 - The superclasses of
ImageAttachmentView
andImageCollectionViewCell
became generic overExtraData
#1111
- Add
areTypingEventsEnabled
,areReactionsEnabled
,areRepliesEnabled
,areReadEventsEnabled
,areUploadsEnabled
toChatChannelListController
#1085 - Add
ImageCDN
protocol to improve work with image cache and thumbnails #1111 - Add missing APIs
open
ofComposerVC
. Including the delegate implementations and showing the suggestions as a child view controller. #1140 - Add possibility to build the
StreamChat
framework on macOS #1132 - Add
scrollToLatestMessageButton
to Message list when there is new unread message #1147
- Fix background color of message list in dark mode #1109
- Fix inconsistent dismissal of popup actions #1109
- Fix message list animation glitches when keyboard appears #1139
- Fix issue where images might not render in the message composer in some cases #1140
- Fix issue with message bubbles not being updated properly when a message withing the same group is sent/deleted #1141, #1149
- Fix jumps on message list when old message is edited or when the new message comes #1148
ThreadVC
,ChatMessageReactionsVC
, andChatMessageRActionsVC
are now configurable viaComponents
#1155- Fix
CurrentUserDTO
not available after completion ofreloadUserIfNeeded
#1153
swipeableViewWillShowActionViews(for:)
andswipeableViewActionViews(for:)
areopen
now #1122- Add
preferredSize
toUIImageView.loadImage
function to utilise ImageCDN functions #1111 - Update
ErrorPayload
access control to expose for client-side handling #1134 - The default time interval for message grouping was changed from 10 to 30 seconds #1141
May 21, 2021
- Refresh authorization token when WebSocket connection disconnects because the token has expired #1069
- Typing indicator inside
ChatMessageListVC
#1073 ChannelController.freeze
and `unfreeze #1090 Freezing a channel will disallow sending new messages and sending / deleting reactions. For more information, see our docs
- Fix crash when opening attachments on iPad #1060 #997
- New channels are now visible even if the user was added to them while the connection was interrupted #1092
⚠️ The defaultBaseURL
was changed from.dublin
to.usEast
to match other SDKs #1078- Split
UIConfig
intoAppearance
andComponents
to improve clarity #1014 - Change log level for
ChannelRead
when it doesn't exist in channel fromerror
toinfo
#1043 - Newly joined members'
markRead
events will cause a read object creation for them #1068
May 03, 2021
ChatChannelListControllerDelegate
now has thecontrollerWillChangeChannels
method #1024
- Fix potential issues with data access from across multiple threads #1024
- Fix warning in
Package.swift
#1031 - Fix incorrect payload format for
MessageController.synchronize
response #1033 - Improve handling of incoming events #1030
April 23, 2021
- All channel events are correctly propagated to the UI.
April 23, 2021
- It's safe now to use
ChatChannel
andChatMessage
across multiple threads #984 - Web socket reconnection logic better handles the "no internet" errors #970
ChatChannelWatcherListController
now correctly loads initial watchers of the channel #1012
- Expose the entire quoted message on
ChatMessage
instead of itsid
#992 - Expose thread participants as a set of
ChartUser
instead of a set ofUserId
#998 ChatChannelListController
removes hidden channels from the list in the real time #1013CurrentChatUser
containsmutedChannels
field with the muted channels #1011ChatChannel
containsisMuted
andmuteDetails
fields with the information about the mute state of the channel #1011- Existing
ChatChannelListController
queries get invalidated when the current user membership changes, i.e. when the current users stops being a member of a channel, the channel stop being visible in the query #1016
- Updating the current user devices is now done manually by calling
CurrentUserController.synchronizeDevices()
instead of being automatically called onCurrentUserController.synchronize()
#1010
ChatMessage.quotedMessageId
is now deprecated. UsequotedMessage?.id
instead #992
April 09, 2021
- Channels are properly marked as read when
ChatChannelVC
is displayed #972 - Channels now support typing indicators #986
- Fix
ChannelController
s created withcreateChannelWithId
andcreateChannelWithMembers
functions not reporting their initial values #945 - Fix issue where channel
lastMessageDate
was not updated when new message arrived #949 - Fix channel unread count not being updated in the real time #969
- Fix updated values not reported for some controllers if the properties were accessed for the first time after
synchronize
has finished. Affected controllers wereChatUserListController
,ChatChannelListController
,ChatUserSearchController
#974
Logger.assertationFailure
was renamed toLogger.assertionFailure
#935
March 29, 2021
- Fix
ChannelDoesNotExist
error is logged byUserWatchingEventMiddleware
when channels are fetched for the first time #893 - Improve model loading performance by lazy loading expensive properties #906
- Fix possible loops when accessing controllers' data from within delegate callbacks #915
- Fix
channel.updated
events failing to parse due to missinguser
field #922 This was due to backend not sendinguser
field when the update was done by server-side auth.
- Introduce support for multitenancy -
teams
forUser
andteam
forChannel
are now exposed. #905 - Introduce support for pinned messages #896
- Expose
pinnedMessages
onChatChannel
which contains the last 10 pinned messages #896 - Expose
pinDetails
onChatMessage
which contains the pinning information, like the expiration date #896 - Add support for pinning and unpinning messages through
pin()
andunpin()
methods inMessageController
#896 - Add new optional
pinning: Pinning
parameter when creating a new message inChannelController
to create a new message and pin it instantly #896 - Add
lastActiveMembers
andlastActiveWatchers
toChatChannel
. The max number of entities these fields expose is configurable viaChatClientConfig.localCaching.chatChannel
#911
ChatChannel.latestMessages
now by default contains max 5 messages. You can change this setting inChatClientConfig.localCaching.chatChannel.latestMessagesLimit
#923
ChatChannel
's propertiescachedMembers
andwatchers
were deprecated. UselastActiveMembers
andlastActiveWatchers
instead #911
March 12, 2021
- Fix app getting terminated in background during an unfinished background task #877
- Introduce
MemberEventMiddleware
to observe member events and update database accordingly #880 - Expose
membership
value onChatChannel
which contains information about the current user membership #885 ChatChannelMember
now contains channel-specific ban information:isBannedFromChannel
andbanExpiresAt
#885- Channel-specific ban events are handled and the models are properly updated #885
March 09, 2021
- Add support for slow mode. See more info in the documentation #859
- Add support for channel watching events. See more info in the documentation #864
- Add support for channel truncating #864
ChatChannelNamer
is now closure instead of class so it allows better customization of channel naming inChatChannelListItemView
.
- Fix encoding of channels with custom type #872
- Fix
CurreUserController.currentUser
returning nil beforesynchronize()
is called #875
February 26, 2021
- Fix localized strings not being loaded correctly when the SDK is integrated using CocoaPods #845
- Fix message list crash when rotating screen #847
February 22, 2021
- Fix user devices not being removed locally when removed on the backend #882
- Fix issue with bad parsing of malformed attachment data causing channelList not showing channels #834
February 12, 2021
- Add support for custom attachment types with unknown structure #795
- Add possibility to send attachments that don't need prior uploading #799
- Improve serialization performance by exposing items as
LazyCachedMapCollection
instead ofArray
#776 - Reduce amount of fake updates by erasing touched objects #802
- Trigger members and current user updates on UserDTO changes #802
- Extracts the connection handling responsibility of
CurrentUserController
to a newChatConnectionController
. #804 - Allow delete/edit message for all users #809 By default, only admin/moderators can edit/delete other's messages, but this configurable on backend and it's not known by the client, so we allow all actions and invalid actions will cause backend to return error.
- Simplify attachment send API by combining
attachment
andattachmentSeeds
parameters. #815
- Fix race conditions in database observers #796
- Revert changeHash that became obsolete after #802 #813
February 2nd, 2021
- Add support for
enforce_unique
parameter on sending reactions #770
- Fix development token not working properly #760
- Fix lists ordering not updating instantly. #768
- Fix update changes incorrectly reported when a move change is present for the same index. #768
- Fix issue with decoding
member_count
forChannelDetailPayload
#782 - Fix wrong extra data cheat sheet documentation link #786
January 22nd, 2021
- Offline support: Browse channels and send messages while offline.
- First-class support for
SwiftUI
andCombine
: Built-it wrappers make using the SDK with the latest Apple frameworks a seamless experience. - Uses
UIKit
patterns and paradigms: The API follows the design of native system SDKs. It makes integration with your existing code easy and familiar. - Currently, 3.0 version is available only using CocoaPods. We will add support for SPM soon.
To use the new version of the framework, add to your Podfile
:
pod 'StreamChat', '~> 3.0'
In order to provide new features like offline support and SwiftUI
wrappers, we had to make notable breaking changes to the public API of the SDKs.
Please don't upgrade to version 3.0
before you get familiar with the changes and their impact on your codebase.
To prevent CocoaPods from updating StreamChat
to version 3, you can explicitly pin the SDKs to versions 2.x
in your podfile
:
pod 'StreamChat', '~> 2.0'
pod 'StreamChatCore', '~> 2.0' # if needed
pod 'StreamChatClient', '~> 2.0' # if needed
The framework naming and overall structure were changed. Since version 3.0, Stream Chat iOS SDK consists of:
Contains low-level logic and is meant to be used by users who want to build a fully custom UI. It covers functionality previously provided by StreamChatCore
and StreamChatClient
.
Contains a complete set of ready-to-use configurable UI elements that you can customize a use for building your own chat UI. It covers functionality previously provided by StreamChat
.
The best way to explore the SDKs and their usage is our sample app. It contains an example implementation of a simple IRC-style chat app using the following patterns:
UIKit
using delegatesUIKit
using reactive patterns and SDK's built-inCombine
wrappers.SwiftUI
using the SDK's built-inObservableObject
wrappers.- Learn more about the sample app at its own README.
- Cheat Sheet Real-world code examples showcasing the usage of the SDK.
- Controller Overview This page contains a list of all available controllers within StreamChat, including their short description and typical use-cases.
- Glossary A list of names and terms used in the framework and documentation.