Swiftpack.co - Package - GetStream/stream-chat-swift

Official iOS/macOS SDK for Stream Chat

|StreamChatClient|StreamChatCore|StreamChat| |:-:|:-:|:-:| |Cocoapods Carthage compatibleSwift Package Manager compatibleClient Documentation|Cocoapods Carthage compatibleSwift Package Manager compatibleCore Documentation|Cocoapods Carthage compatibleSwift Package Manager compatibleUI Documentation|

stream-chat-swift is the official iOS SDK for Stream Chat, a service for building chat and messaging applications. This SDK also supports macOS via Mac Catalyst.

Quick Links

Swift/iOS Chat Tutorial

The best place to start is the iOS Swift Chat Tutorial. It teaches you how to use this SDK and also shows how to make frequent changes.

Example App

This repo includes a fully functional example app with setup instructions. It is available under the Example folder.


You'll typically want to start out using the UI components, and implement your components using the Swift Chat API as needed.


  • iOS 11+/macOS 10.15+
  • Xcode 11.2+
  • Swift 5.2
  • CocoaPods 1.7+
  • Carthage 0.33.0+

Mac Catalyst

Our frameworks are compatible with Mac Catalyst, meaning you can create a chat application that works on both iOS and macOS. Read about it here.

⚠️ Carthage does not support Mac Catalyst yet. (ref)


Stream Chat SDK consists of three frameworks: StreamChat, StreamChatCore and StreamChatClient

  • StreamChatClient - the low-level library that connects & communicates with StreamChat backend.
  • StreamChatCore — building on top of StreamChatClient, it includes models, presenters, and notification manager. Additionally, it has RxSwift support for reactive programming.
  • StreamChat — building on top of Core, it's the full SDK library with all UI components. Styling and deep customizations are all supported out of the box.


To integrate StreamChat into your Xcode project using CocoaPods, add this entry in your Podfile:

pod 'StreamChat'

Then run pod install.

If you want to use only StreamChatCore or StreamChatClient', you can add this entry in yourPodfile`:

pod 'StreamChatCore'
# or
pod 'StreamChatClient'

In any file you'd like to use Stream Chat in, don't forget to import the frameworks:

import StreamChat

or if you are working with the low-level client or Core:

import StreamChatCore
// or
import StreamChatClient


To integrate Stream Chat into your Xcode project using Carthage, specify it in your Cartfile:

github "GetStream/stream-chat-swift"

Then run: carthage update --platform iOS --new-resolver. It will build the frameworks: StreamChatClient.framework, StreamChatCore.framework and StreamChat.framework into <Path to your Project>/Carthage/Build/iOS/ from where you can add them to your project and link them with your app target. Follow with these steps:

  • Open your Xcode project

  • Select the project in the Navigator

  • Select your app target

  • Open General panel

  • Open <Path to your Project>/Carthage/Build/iOS/ in Finder and find StreamChatClient.framework, drag and drop it into Frameworks, Libraries, and Embedded Content area in Xcode. Do the same for StreamChatCore.framework and StreamChat.framework if you need UI components.

  • After adding libraries, select "Do Not Embed" option in "Embed" section. (Right next to the library name after adding it)

  • Open Build Phases panel in Xcode

  • Click the + button and select New Run Script Phase

  • Set the content to: /usr/local/bin/carthage copy-frameworks

  • Add to Input Files:

    • $(SRCROOT)/Carthage/Build/iOS/StreamChatClient.framework

    • $(SRCROOT)/Carthage/Build/iOS/Starscream.framework

    • if you need Core library:

      • $(SRCROOT)/Carthage/Build/iOS/StreamChatCore.framework
      • $(SRCROOT)/Carthage/Build/iOS/RxSwift.framework
      • $(SRCROOT)/Carthage/Build/iOS/RxCocoa.framework
      • $(SRCROOT)/Carthage/Build/iOS/RxRelay.framework
    • if you need UI components:

      • $(SRCROOT)/Carthage/Build/iOS/StreamChat.framework
      • $(SRCROOT)/Carthage/Build/iOS/Nuke.framework
      • $(SRCROOT)/Carthage/Build/iOS/SnapKit.framework
      • $(SRCROOT)/Carthage/Build/iOS/SwiftyGif.framework
      • $(SRCROOT)/Carthage/Build/iOS/RxGesture.framework
  • Add to Output Files:

    • $(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/StreamChatClient.framework

    • $(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Starscream.framework

    • if you need Core library:

      • $(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/StreamChatCore.framework
    • if you need UI components:

      • $(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/StreamChat.framework ()

Now you can build your app and use StreamChat.

Swift Package Manager

You can directly add dependency in Xcode 11+ using repo url, or in your Package.swift file, add to dependencies:

.package(url: "https://github.com/GetStream/stream-chat-swift.git", from: "2.3.0"),

Supported features

  • Group chat
  • Channel list
  • Reactions
  • Rich link preview (e.g. open graph)
  • Attachments (images, videos and files)
  • Commands (e.g. /giphy)
  • Editing messages
  • Typing events
  • Read events
  • Threads
  • Notifications
  • Opening a link in the internal browser
  • Image gallery
  • GIF support
  • Light/Dark theme
  • Style customization
  • UI customization


Stars: 86

Used By

Total: 0


2.3.2 - 2020-09-04 15:28:46

✅ Added

  • A a new method for ChatViewController to customize behaviour for a tap on an attachment: tapOnAttachment(_ attachment: Attachment, at index: Int, in cell: MessageTableViewCell, message: Message) #466

🐞 Fixed

  • Carthage building incorrect (v3-alpha) version instead of 2.3.0 and 2.3.1. If you're using Carthage, please skip these versions. #468

2.3.1 - 2020-08-31 13:43:22

🔄 Changed

  • User changed from struct to class, to prevent Atomic crashes #450

🐞 Fixed

  • user.unbanned event cannot be listened for #449

2.3.0 - 2020-08-31 09:39:40

✅ Added

  • ChannelsPresenter.delete & ChannelsPresenter.rx.delete methods to delete a channel and remove it from items list #394
  • Mute/unmute a channel #428
    • Client.shared.mute(channel: channel) {} or channel.mute {}
    • Client.shared.rx.mute(channel: channel) or channel.rx.mute()
  • .notificationChannelMutesUpdated event type to get the current user updated when a channel was muted or unmuted #428
  • The memberCount variable added to Channel with the total number of members in the channel. It's no longer needed to query all members and count them #442
  • ChannelsQuery.membersLimit field added to ChannelsQuery. It's possible to limit the number of Member objects returned in the channel payload. When you query the channels and you don't need the members objects to be presented, setting this value to a lower number should significantly improve the overall performance. #442
  • ClientLogger measures the durations of API requests and JSON parsing. It's enabled by default on the .debug level #442
  • ClientLogger.logTaskStarted() and ClientLogger.logTaskFinished() API added for performance measurements #442

🔄 Changed

  • Podspec and Package Swift versions bumped to 5.2 #438

🐞 Fixed

  • Channels list (ChannelsViewController) not updated when recreating a channel after deleting it #392
  • If the user (JWT) token expires and websocket disconnects due to it, Client will renew the expiring JWT token and reconnect websocket automatically #429
  • Date separators in a chat appear after a new message #440
  • Device object sometimes failing to decode on API calls #266

2.2.9 - 2020-08-12 18:43:59

✅ Added

  • To improve request latency, we use the time while the WS connection is establishing to open a new TCP connection, which can later be reused by other requests. #401

🐞 Fixed

  • HTTP pipelining is enabled to improve request response times for situations when the clients and servers are in different regions #396

2.2.8 - 2020-08-07 16:52:14

✅ Added

  • Membership for a channel #387

🔄 Changed

  • Remove the need for querying members in order to mark a channel as read #280

🐞 Fixed

  • Use total unread count from message.new event #384
  • Unread count calculation for disabled read messages feature #387

2.2.7 - 2020-07-29 14:13:43

✅ Added

  • Client.Config.webSocketProvider for selecting a websocket provider #357
  • Parameters to allow custom mention parsing logic. If set to false, Message.mentionedUsers is not overridden on send. #338
    • parseMentionedUsers: Bool = true parameter in Client.send(message: ...).
    • parseMentionedUsers: Bool = true parameter in ChannelPresenter.send(text: ...).
    • parseMentionedUsersOnSend: Bool = true property in ChatViewController.
  • Message search with filter for messages #348
    • Client.search(filter: Filter, messageFilter: Filter, ...) #348
    • SearchQuery.init(filter: Filter, messageFilter: Filter, ...) #348
  • Filter.exists(Key, Bool) #348
  • Channels created without explicit name/image will get default names generated for them, using their members' names #366

🔄 Changed

  • All iOS versions will use Starscream as default websocket provider until native provider issue is resolved. See #315. #357

🐞 Fixed

  • Reintroduce Hashable conformances removed in 2.2.1 #368
  • ChannelPresenter.lastMessage not updated on message edited or deleted #351
  • Link tap in messages sometimes not detected or detected in wrong place #350
  • Device object sometimes failing to decode on API calls #266
  • Direct message channel (created without explicit id, using Client.shared.channel(type:members:)) are named correctly #366
  • Flagging current user's (own) messages are now allowed #369

2.2.6 - 2020-07-07 16:08:23

✅ Added

  • ChatViewController.preferredEmojiOrder to specify order of emojis in reaction view #337
  • Unban a user API:
    • client.unban(user:User in channel: Channel, _ completion:) #344
    • client.rx.unban(user:User in channel: Channel) #344
    • channel.unban(user:User, _ completion:) #344
    • channel.rx.unban(user:User) #344

🐞 Fixed

  • Increasing username label font size (MessageViewStyle.nameFont) in message cell caused cut off #333
  • Emojis in reaction view not displayed consistent order #332

2.2.5 - 2020-06-24 15:10:48

⚠️ Deprecated

  • UsersQuery.sort property is deprecated, please use UsersQuery.sorting #328

✅ Added

  • Message.translate for message translations. Please see docs for more info #319
  • user.unbanned event added #319
  • PinStyle for ComposerViewStyle with options #329:
    • .floating - shows ComposerView over messages (by default).
    • .solid - shows messages above ComposerView with a ComposerViewStyle top edge inset.
  • queryUsers with multiple sorting options support #328 Signature: queryUsers(filter:sorting:pagination:options:completion)

🐞 Fixed

  • queryUsers and UsersQuery now respect sorting parameter #328

2.2.4 - 2020-06-12 15:53:42

✅ Added

  • ClientLogger.showConnectionErrorAlert flag to control showing the UI alert for WebSocket errors. It's turned off by default. #303

🔄 Changed

  • Calling Client.configureShared with the same config more than once does not cause assertion failure. This is still discouraged and should not be done, and will not take affect. Calling it with different configs will still cause assertion failure. #313 Note: Changing apiKey only is possible via Client.shared.apiKey

🐞 Fixed

  • Channel.team not being correctly encoded for multi-tenant enabled clients #308
  • Channels not loading on ChannelsVC after opening the app from background using stayConnectedInBackground: false and no logger #308
  • Fixed an error in ChatViewController: a new message would scroll the messages up even when there's empty space #310.
  • Fixed the default background color for a placeholder image or when the image wasn't loaded to make the size of it visible #310.
  • Fixed height rendering for a message for messages with a single line #310.
  • Fixed rendering of a message bubble curve more precisely #310.
  • Fixed scrolling to the current message when you go to the last page #310.
  • Fix ChannelsPresenter not respecting filter for new created/added channels #313

2.2.3 - 2020-06-05 15:04:56

✅ Added

  • Support new regions: Singapore and Sydney. #293
  • disableLocalNotifications added to Notifications for disabling local notifications #290
  • Send a keystroke event for the current user: channel.keystroke {}. The method will automatically send a typing stop event after 15 seconds after the last call of keystroke(). #281
  • Send a stop typing event for the current user: stopTyping {}. Usually, you don't need to call this method directly. #281
  • Automatically send a typingStop event if it's not received in 30 seconds after the latest typingStart event #282.
  • Add support for multi-tenancy. Refer to docs for more info #295

🔄 Changed

  • Unknown user is not used anymore. By default the current user is anonymous (you can check this with isAnonymous). Anyway you can't connect without set(user:token:) or setGuestUser(user:) or setAnonymousUser() #284.
  • You can subscribe to events as soon as the client is configured. This means that your subscriptions will work until the client disconnect (user login/logout) and until you cancel subscriptions #284.

🐞 Fixed

  • Fixed rx.connectionState observation when a user logged out and login again #284.

2.2.2 - 2020-05-27 15:09:39

✅ Added

  • Re-introduced Filter.none. It should not be used with queryChannels or search, it's only valid for queryUsers to get all users #285
  • Filter.contains operator for all endpoints #285
  • Filter.custom to be able to use new operators before our SDK is updated #285 Please make sure to provide a valid operator. Example: .custom("contains", key: "teams", value: "red")
  • queryUsers now supports Pagination.limit and Pagination.offset #288

2.2.1 - 2020-05-19 17:06:18

✅ Added

  • Added ClientLogger.iconEnabled, ClientLogger.dateEnabled, and ClientLogger.levelEnabled to control what will be shown in logs. These will only be valid when ClientLogger.logger block is not customized (overridden) #263
  • silent property added to messages, see docs here #264
  • Added option to show message replies also in channel, just like Slack #271.
  • A new view style for a reply in a channel ComposerViewStyle.ReplyInChannelViewStyle. You can set this style to nil for your composerViewStyle to disable this feature #271.

🔄 Changed

  • ClientLogger.logger is deprecated, please use ClientLogger.log block to customize your log output #263
  • Logs will now output log level, access it when overriding ClientLogger.log block #263
  • By default, logs will not output emoji icons anymore, but all logs will now output date #263

🐞 Fixed

  • set(user:) is not required for query (channels, users) unless presence: true or state: true is specified #269
  • Disabled context menu for deleted messages: #241.
  • Fix crash in iOS12 caused by abstract URLSession instance #272
  • Fix infinite loop when the web socket connection fails (iOS13 only) #273.
  • Direct message channels (1-by-1 channels) will correctly get their name and avatar image from other user #275.
let anotherUser = User(id: "second")
anotherUser.name = "John"
anotherUser.avatarURL = URL(string: "http://example.com/john")

let channel = client.channel(members: [client.user, anotherUser])
print(channel.name) // will print "John"
print(channel.imageURL) // will print "http://example.com/john"

2.2.0 - 2020-05-08 12:36:19

✅ Added

  • avatarViewStyle under ChatViewStyle for customizing Navigation Right Bar Button Item avatar #241.
  • logAssert(_:_:) and logAssertionFailure(_:) functions added to ClientLogger #231.
  • queryChannels now returns unread count of each channel, unrestricted by number of messages fetched #247: Example:
    Client.shared.queryChannels(filter: .currentUserInMembers, sort: [Sorting("has_unread", isAscending: false)]) { (result) in
        for response in result.value! {
            print("Channel \(response.channel.name ?? "nil"), unread messages count: \(response.channel.unreadCount.messages)")

🔄 Changed

  • Configuring the shared Client using the static Client.config variable has been deprecated. Please create an instance of the Client.Config struct and call Client.configureShared(_:) to set up the shared instance of Client #231.

    // Deprecated:
    Client.config = .init(apiKey: apiKey, logOptions: .info)
    // Preferred:
    var config = Client.Config(apiKey: apiKey)
    config.logOptions = .info

    Reasoning: In the original implementation, when Client.shared was accessed for the first time, its initializer used the current value of Client.config. In more complex situations, this approach could cause hard-to-debug race-condition bugs when Client.shared was initialized before its configuration was fully finished. The newly introduced Client.configureShared(_:) function makes the client configuration explicit.

  • Client.shared triggers assertion failure when used without configuring #231.

  • Client.Config triggers assertion failure when created with an empty API key value #231.

  • Assigning an empty string to Client.apiKey triggers assertion failure #231.

  • Changed title of camera upload button from Upload from a camera to Upload from camera #239.

  • Deprecated 2 public initializers from UploadingItem #239:

    public init(attachment:previewImage:previewImageGifData:)


    public init(attachment:fileName:)

    since they were unused. Please use init(channel:url:) initializer.

  • Atomic.get(default: T) -> T function was deprecated for non-optional T #241

  • Atomic.get() no longer returns an optional type if the wrapped type itself is not optional #241

  • Atomic.init(_:) requires the initial value for non-optional T #241

  • Atomic.DidSetCallback signature changed from (_ value: T?, _ oldValue: T?) -> Void to (_ value: T, _ oldValue: T) -> Void #241

🐞 Fixed

  • Fix rx observing for the connection state #249.
  • Images taken directly from camera do not fail to upload #236.
  • Video uploads are now working, videos are treated as files #239.
  • Files over 20MB will correctly show file size warning #239.
  • Fix last message not set when sending first message to an empty channel #246.
  • Show in logs if extra data decoding failed for the User or Channel #238.
  • Recover the default extra data for User and Channel types #238.
  • Crashes on channel.rx.events and channel.rx.unreadCount #248.
  • It's now possible to access Atomic value within its own update { } block #251
  • Fixed warning in AutoCancellingSubscription #256

2.1.1 - 2020-05-01 17:06:05

🐞 Fixed

  • Fix keyboard disappearing after every message #227.
  • Suppress local notifications for muted users #234.
  • Unread count for deleted messages #223.
  • Public access to set ChannelPresenter.uploadManager to use custom Uploader #232.
    • ⚠️ Please be sure to call progress and completion callbacks on the main thread.

2.1.0 - 2020-04-29 11:27:27

⚠️ Breaking Changes

  • Set user will return a Result<UserConnection, ClientError> in callback. UserConnection has the current user data, connection id and unread count for channels and messages #182.
  • AvatarView.init changed and it requires AvatarViewStyle intead of cornerRadius and font #203.
  • Renamed #100:
    • ChannelPresenter.uploader to ChannelPresenter.uploadManager,
    • UploadItem to UploadingItem.
  • Modified signatures #100:
func sendImage(data: Data, 
               fileName: String, 
               mimeType: String, 
               channel: Channel,
               progress: @escaping Client.Progress, 
               completion: @escaping Client.Completion<URL>) -> Cancellable

func sendFile(data: Data,
              fileName: String,
              mimeType: String,
              channel: Channel,
              progress: @escaping Client.Progress,
              completion: @escaping Client.Completion<URL>) -> Cancellable
func deleteImage(url: URL, channel: Channel, _ completion: @escaping Client.Completion<EmptyData> = { _ in }) -> Cancellable

func deleteFile(url: URL, channel: Channel, _ completion: @escaping Client.Completion<EmptyData> = { _ in }) -> Cancellable

🔄 Changed

  • Pagination doesn't support + operator anymore, please use a set of PaginationOptions from now on #158.
  • channel.subscribeToWatcherCount uses channel events to publish updated counts and does not call channel.watch as a side-effect anymore #161.
  • Subscriptions for a channel unread count and watcher count #172.
  • Changed a returning type for requests as Cancellable instead of URLSessionTask to make requests and events more consistent #172.
  • The example project was updated #172.
  • Rename showImagePickerAuthorizationStatusAlert to showImagePickerAlert #215

✅ Added

  • Message preparation callback on ChannelPresenter to modify messages before they're sent #142.
  • The view controller for threads can now be customized by overriding createThreadViewController in ChatViewController. This is useful if you need a different style for threads. #136.
  • Better errors when developers forget to call set(user:) or don't wait for its completion #160.
  • Examples for a channel unread count and watcher count in the Example app #172.
  • Added ChatViewStyle.default #191.
  • Added ChatViewStyle.dynamic for iOS 13 to support dynamic colors for dark mode #191.
  • Added MessageViewStyle.pointedCornerRadius to make pointed corner rounded #191.
  • Added methods for AvatarView customization #203:
  • Added messageInsetSpacing to MessageViewStyle to allow control of spacing between message and container #216.
  • Added Uploader protocol. Use them to create own uploader for your file storage. Assign your uploader into ChannelPresenter #100:
presenter.uploadManager = UploadManager(uploader: customUploader)


open func updateChannelCellAvatarView(in cell: ChannelTableViewCell, channel: Channel)


open func updateMessageCellAvatarView(in cell: MessageTableViewCell, message: Message, messageStyle: MessageViewStyle)
open func updateFooterTypingUserAvatarView(footerView: ChatFooterView, user: User)
  • New properties for AvatarViewStyle #203:
    • placeholderTextColor: UIColor?
    • placeholderBackgroundColor: UIColor?
  • Added Uploader protocol. Use them to create own uploader for your file storage. Assign your uploader into ChannelPresenter #100:
  presenter.uploadManager = UploadManager(uploader: customUploader)

🐞 Fixed

  • SPM support #156.
  • Made SubscriptionBag.init public #172.
  • Unused RxBlocking dependency removed #177.
  • Reconnection now automatically re-watches all channels watched up to that point #178.
  • Unnecessary Gzip dependency removed #183.
  • Unnecessary Reachability dependency removed #184.
  • Flag message/user #186.
  • Discard messages from muted users #186.
  • Fix composerView hiding behind keyboard after launching from bg #188.
  • Open prepareForReuse() in ChannelTableViewCell and MessageTableViewCell #190.
  • Channel query options default to .state, in-line with documentation instead of empty #198
  • Fix the deprecation warning in the UI framework #201.
  • Fix current user's messages are counted towards unread count #206
  • Fix ImagePicker not asking for permission for avaible source types #215
  • Fix ImagePicker showing an error when no image is selected #215

2.0.0 - 2020-04-02 16:45:29

StreamChat 2.0 here and it's brand new :sparkles: :rocket:

We've added/removed/fixed/changed a lot of stuff, so it's fair to say that StreamChat 2.0 is everything you've liked about 1.x and nothing you didn't like about it :smile:

Most importantly:

  • We have a brand new framework: StreamChatClient, that you can use to easily integrate StreamChat into your app without any Presenter or UI logic we have in StreamChatCore and StreamChat libraries.
    • StreamChatClient has minimal dependencies and it's very low level.
    • No Reactive dependencies! Everything is handled in good old callbacks.
    • No reactive makes you sad? StreamChatCore still has all the reactive functionality you'd expect, so you can keep using RxSwift if you want!
  • We've updated our dependencies, and removed some.

Aside from those, we fixed tons of bugs and polished our API. Now it should be more Swifty :tada: We're working hard on migration guide for our 1.x users and will publish it shortly. You can check out updated docs here

1.6.2 - 2020-04-02 09:41:21

🐞 Fixed

  • 1.6.1 build error caused from dependency misconfiguration #147

1.6.1 - 2020-03-18 15:07:42

🐞 Fixed

  • (UI Components) Typing events are now reliably sent #122

1.6.0 - 2020-03-10 15:05:59

⚠️ Breaking Changes

  • Removed hard-coded reactions. #113
  • Reaction API changed: addReaction requires a reaction object instance of reaction type. #113

✅ Added

🐞 Fixed

  • Error description of failed request is now human-readable #104

1.5.7 - 2020-02-14 15:06:10

🐞 Fixed

  • Fixed "nested frameworks are not allowed" error when using Carthage #100
  • Fixed strikethrough markdown with ~~ correctly applied #97
  • Fixed "connectionId is empty" error when app becomes active after disconnecting #70

1.5.6 - 2020-02-11 12:35:26

🔄 Changed

  • Failed uploads now retry up to 3 times #85

✅ Added

  • Swift Package Manager (SPM) support #38
  • ViewController.showAlert(title:message:actions:) now you can override this function to decide when/how alerts should be handled #85
  • Allow user to go directly to iOS settings if they've disabled photo library access and trying to upload image/video #85

🐞 Fixed

  • Fixed allowing file uploads exceeding API file limit (20MB) and crashing #81
  • Fixed internet connection losses during image uploads cause crashing #82
  • Fixed previewing uploaded videos crashing on iOS12 #83
  • Fixed pan gestures on ComposerView affect chat table view #95

1.5.5 - 2020-01-24 15:35:40

🔄 Changed

  • Handling keyboard notifications for ChatViewController in rx, robust way.

✅ Added

  • Banner animation without bouncing.
  • Customization for message actions.
  • Added Event.reactionUpdated.
  • Opened MessageTableViewCell.
  • Opened ChannelTableViewCell.
  • More customization for a message and channel cells.
    • Added AvatarViewStyle
    • Added SeparatorStyle
    • Added Spacing
    • Added ChannelTableViewCell.VerticalTextAlignment
    • MessageTableViewCell.avatarViewStyle: AvatarViewStyle?
    • MessageTableViewCell.spacing: Spacing
    • MessageTableViewCell.edgeInsets: UIEdgeInsets
    • ChannelTableViewCell.avatarViewStyle: AvatarViewStyle?
    • ChannelTableViewCell.separatorStyle: SeparatorStyle
    • ChannelTableViewCell.nameNumberOfLines: Int
    • ChannelTableViewCell.messageNumberOfLines: Int
    • ChannelTableViewCell.height: CGFloat
    • ChannelTableViewCell.spacing: Spacing
    • ChannelTableViewCell.edgeInsets: UIEdgeInsets
    • ChannelTableViewCell.verticalTextAlignment: VerticalTextAlignment
  • Added a customization for message actions.

🐞 Fixed

  • Fixed example app memory leak.
  • Fixed keyboard events replaying unexpectedly.
  • Scroll the table view to the bottom safely.
  • Fixed a crash when the token was expired.
  • Fixed StatusTableViewCell layout.
  • Fixed video attachments are not recognized and not clickable. #56
  • Fixed ComposerView going behind keyboard when an opaque TabBar is used. #64
  • Fixed WebView crashing when file picker is presented in a website in iPhones. #69
  • Fixed messages not being grouped correctly after one day. #72

- 2020-01-08 14:08:30

Fixed a crash when the token has expired.

- 2019-12-16 15:35:55

💥 Breaking Changes

  • The order of parameters in Message.init
  • Removed members from ChannelResponse. Now it's only inside the channel of the response.

🔄 Changed

  • Improved Token validation.

✅ Added

  • Public Attachment.init(...).
  • Public Reaction.init(...).
  • Public Reaction(counts: [ReactionType: Int]).
  • Public User.unknown.
  • Example app with Cocoapods.
  • Example app with Carthage.
  • A new authorization in the Example app.
  • ✈️ Offline mode inside InternetConnection.
  • Improved connection flow.
  • Extension Data.hex.
  • Extension String.md5, String.url?.
  • Filter.description.
  • Sorting.description.
  • A variable JSONDecoder.default. Now you can change the default JSON decoder.
  • Variables JSONEncoder.default and JSONEncoder.defaultGzip. Now you can change default JSON encoders.
  • A channel for a direct messages will use a member avatar as default channel image by default.
  • Docs for the ClientLogger.
  • Hide a channel with clearing messages history.
  • Added a new event Event.channelHidden(HiddenChannelResponse, EventType).

🐞 Fixed

  • ComposerView position related to the keyboard with an opaque UITabBar.
  • A proper way to check if members are empty.

- 2019-11-27 14:42:22

  • Fix tap on a link with disabled reactions.

- 2019-11-27 14:41:53


  • Client.channel(query: ChannelQuery)


  • ComposerView and keyboard events crashes.
  • ComposerView position for embedded ChatViewController.
  • Parse now can properly ignore bad channel name.

- 2019-11-26 22:21:28


  • Layout ComposerView depends on keyboard events.


  • Token update.

- 2019-11-23 00:47:23


  • Added levels for ClientLogger.

    • Error Level:
      • ClientLogger.Options.requestsError
      • ClientLogger.Options.webSocketError
      • ClientLogger.Options.notificationsError
      • ClientLogger.Options.error — all errors
    • Debug Level:
      • ClientLogger.Options.requests
      • ClientLogger.Options.webSocket
      • ClientLogger.Options.notifications
      • ClientLogger.Options.debug — all debug
    • Info Level:
      • ClientLogger.Options.requestsInfo
      • ClientLogger.Options.webSocketInfo
      • ClientLogger.Options.notificationsInfo
      • ClientLogger.Options.info — all info
  • MessageViewStyle.showTimeThreshold to show additional time for messages from the same user at different times.

. . . AdditionalDateStyle.messageAndDate . . . . AdditionalDateStyle.userNameAndDate . . .

  • Optimized MessageTableViewCell rendering.

  • Channel name. If it's empty:

    • for 2 members: the 2nd member name
    • for more than 2 members: member name + N others.
    • channel id.
  • Channel.isDirectMessage — checks if only 2 members in the channel and the channel name was generated.

  • Improved work with ExtraData.

  • A custom ChannelType.custom(String)


  • Removed a channelType parameter in ChannelsPresenter.init.
  • Renamed ExtraData.data -> ExtraData.object
  • Channel.currentUnreadCount update.


  • Detecting and highlighting URL's in messages.
  • Skip empty messages.
  • ChatFooterView with a white circle.
  • A user avatar missing.

- 2019-11-23 00:08:01

Fixed DataDetector.

- 2019-11-14 14:57:14


  • The current user mentioned unread count
// The current unread count.
let count: Int = channel.currentMentionedUnreadCount

// An observable unread count.
    .drive(onNext: { count in
    .disposed(by: disposeBag)
  • Map an observable value to void. .void()