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

Official iOS SDK for Stream Chat

Stream Chat

Language: Swift 5.0 Build Status Code Coverage

StreamChatCore Cocoapods Carthage compatible Swift Package Manager compatible Core Documentation

StreamChat Cocoapods Carthage compatible Swift Package Manager compatible UI Documentation

stream-chat-swift is the official iOS SDK for Stream Chat, a service for building chat and messaging applications.

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 common changes.

Example App

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


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


  • iOS 11+
  • Xcode 11.2+
  • Swift 5.1
  • CocoaPods 1.7+
  • Carthage 0.33.0+


Stream Chat SDK consists of two frameworks: StreamChat and StreamChatCore

  • StreamChat — the full SDK library with all UI components. Styling and deep customizations are all supported out of the box.
  • StreamChatCore — low-level library to use Stream Chat APIs. It includes models, presenters, notification manager and HTTP interface.


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, you can add this entry in your Podfile:

pod 'StreamChatCore'

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

import StreamChat

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

import StreamChatCore


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. This will build frameworks: 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 StreamChatCore.framework, drag and drop it into Frameworks, Libraries and Embedded Content area in Xcode. Do the same for 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/StreamChatCore.framework
    • $(SRCROOT)/Carthage/Build/iOS/StreamChat.framework (if you need UI components)
  • Add to Output Files:
    • $(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/StreamChatCore.framework
    • $(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/StreamChat.framework (if you need UI components)

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: "1.5.5"),

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: 40

Used By

Total: 0


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()

- 2019-11-12 17:25:34


  • A custom data for User.
  • Detect links in messages and open them in WebView.

- 2019-11-11 14:18:18

Fixed ComposerView for a keyboard position with different orientations and opaque Tabbar.

- 2019-11-08 17:38:34

⚠️ The update contains breaking changes.


  • Channel.currentUnreadCount value to show the number in table view.
  • Get a message by id: Client.message(with messageId: String)
  • Mark all messages as reader: Client.markAllRead()
  • User.isInvisible
  • Flag/unflag users: Client.flag(user: User) or user.flag().
  • Ban user: Chanel.ban(user: User, timeoutInMinutes: Int? = nil, reason: String? = nil).
  • Channel ban options: Channel. banEnabling:
/// Disabled for everyone.
case disabled

/// Enabled for everyone.
/// The default timeout in minutes until the ban is automatically expired.
/// The default reason the ban was created.
case enabled(timeoutInMinutes: Int?, reason: String?)

/// Enabled for channel members with a role of moderator or admin.
/// The default timeout in minutes until the ban is automatically expired.
/// The default reason the ban was created.
case enabledForModerators(timeoutInMinutes: Int?, reason: String?)
  • Event userBanned
  • Debug info when API key is empty.
  • More logs for Notifications errors.
  • ChannelPresenter. messageRead for the current user.
  • Client API key property is public and mutable for development in different environments. Not recommended for production.
  • Hiding the keyboard on landscape mode to add attachments.
  • Message search.
  • New flow to invite members to a channel:
// 1. Invite members with a creating a new channel
let channel = Channel(type: .messaging,
                      id: "awesome-chat", 
                      members: [tomasso, thierry]
                      invitedMembers: [nick])

channel.create().subscribe().disposed(by: disposeBag)

// 2. Invite user(s) to an exists channel.
channel.invite(nick).subscribe().disposed(by: disposeBag)


  • ChannelsQuery: .messageLimit.messagesLimit.
  • User: .online.isOnline.


  • ClientLogger updated
  • Atomic from:
typealias DidSetCallback = (T?) -> Void


typealias DidSetCallback = (_ value: T?, _ oldValue: T?) -> Void
  • Channel.watch(options: QueryOptions = []) with query options.


  • BannerView memory leak.
  • A bug with the composer attachment button, when a channel config wasn't loaded.
  • ComposerView position with opaque Tabbar.
  • Reconnection after sleep for 10+ minutes.
  • Popup menu for iPad.
  • ReactionsView for iPhone in landscape orientation.
  • ComposerView bottom constraint when iPhone on the landscape orientation.

- 2019-11-08 17:15:33


  • Events filter in presenters.

- 2019-11-08 17:14:26


  • Update a channel data: update(name: String? = nil, imageURL: URL? = nil, extraData: Codable? = nil)
  • Channel.watch()

- 2019-11-08 17:12:30


  • Response errors
  • A crash of a date formatter for iOS 11.1 and below.

- 2019-10-21 13:05:39


  • ChannelId type (id: String + type: ChannelType).
  • Added Channel.add(members:), Channel.remove(members:).
  • ChannelsViewController will update the table view with only invalidated rows or reload completely.
  • ChannelPresenter.channelDidUpdate observable (for example to get updated members).


  • Client.userDidUpdate as Driver.


  • ChannelsViewController UI warnings. It tries to update itself when it's not in the hierarchy view.

- 2019-10-21 12:54:30


  • ClientError.errorMessage case with a message of error type.
  • Shows a banner for banned users when they try to send a message.
  • Client.userDidUpdate observables.

- 2019-10-21 12:51:44


  • Channel.Config.uploadsEnabled property. You can manage the uploading feature in the Dashboard.


  • Expired token.

- 2019-10-21 12:49:32


  • User.isBanned property. You'll get this property updated when the client will be connected.
  • iPad support for a split view controller (please, check example project).


  • Parsing of an optional attachment file size.

- 2019-10-21 12:45:06


  • Support expired Token's with a token provider:
Client.shared.set(user: user) { tokenProvider in
    YourClient.shared.getToken { token in
  • More flexibility of Push Notifications setup for hosted apps.
  • A local notification body with an attachment file name.


  • ChannelPresenter for creating a channel for 1-by-1.
  • The content channel type value for notifications.
  • ChatViewController for UI warnings.
  • ComposerView for different safe areas.
  • UITextView height in the ComposerView in combinations with attachments.

1.3.13-core - 2019-10-11 12:19:44


  • BaseURL with a custom URL more flexible: BaseURL(customURL: URL(string: "chat-server.com")!)
  • A convenience Channel init for a 1-by-1 chat:

public convenience init(type: ChannelType, with member: Member, extraData: Codable? = nil)

- 2019-10-11 12:16:00


  • A custom URL for BaseURL.
  • Show a Giphy link as a gif image.


  • Uploading a photo from the camera.
  • Mentioned users in a message.

- 2019-10-11 12:12:59


  • Presenter has a new property hasNextPage.
  • A user info key channelType for Push Notifications.


  • Error message for the sending mark read event for channels with disabled the read message feature.
  • Crash in AvatarView for user name test.
  • A disabled keyboard bug for none messaging channels.
  • Bugs filtering channels by id + type.

- 2019-10-08 16:19:35


  • Hide/show channel from a list of channels (Channel.hide(), Channel.show())
  • Channel.stopWatching() to stop receiving events from web sockets.


  • Updating new channels for their messages.
  • Fixed parsing of user info from push notifications.

- 2019-10-08 16:15:44


  • ChannelsViewController.defaultStyle and ChatViewController.defaultStyle for easer way to override the style in subclasses.


  • Notifications more flexible for push notifications to use in hosted apps.


  • Unread count for own messages.
  • Members in channels.

- 2019-10-08 16:10:56


  • Client.disconnect() will disconnect from web sockets and the current user will be logged out.
  • ViewChanges.disconnected for user log out.
  • Added style for an unread channel name.


  • ChannelsPresenter has no filter or sorting. By default channels sorted on server side by the last message date.


  • ChannelsViewController for user log out.

- 2019-10-01 15:00:35


  • Unread observable state for Channel.
  • Unread state for ChannelPresenter.


  • ChannelsPresenter init with filter and sorting parameters.
  • The default filter for channels in ChannelsPresenter changed to filter by members with the current user id.
  • Cleaned up Client.onEvent methods. Required a Channel instead of channelType+channelId.

- 2019-10-01 14:56:40


  • channel.deleted event.
  • ChannelsViewController.deleteChannelBySwipe if enabled, user can delete a channel by swiping a table cell.


  • Example project updated. Channels with dark mode has a plus button to add a new random channel.