Giter Club home page Giter Club logo

getstream / stream-chat-swift Goto Github PK

View Code? Open in Web Editor NEW
804.0 45.0 189.0 290.44 MB

πŸ’¬ iOS Chat SDK in Swift - Build your own app chat experience for iOS using the official Stream Chat API

Home Page: https://getstream.io/chat/sdk/ios/

License: Other

Swift 98.50% Ruby 0.57% Objective-C 0.03% Shell 0.31% Python 0.24% JavaScript 0.32% Makefile 0.04%
chat-sdk swift ios chat-api chat chat-application messaging stream-chat swift-chat ios-chat-sdk

stream-chat-swift's Introduction

StreamChat StreamChatUI

This is the official iOS SDK for Stream Chat, a service for building chat and messaging applications. This library includes both a low-level SDK and a set of reusable UI components.

Low Level Client (LLC)

The StreamChat SDK is a low level client for Stream chat service that doesn't contain any UI components. It is meant to be used when you want to build a fully custom UI. For the majority of use cases though, we recommend using our highly customizable UI SDK's.

UIKit SDK

The StreamChatUI SDK is our UI SDK for UIKit components. If your application needs to support iOS 13 and below, this is the right UI SDK for you.

SwiftUI SDK

The StreamChatSwiftUI SDK is our UI SDK for SwiftUI components. If your application only needs to support iOS 14 and above, this is the right UI SDK for you. This SDK is available in another repository stream-chat-swiftui.


Main Features

  • Offline support: Browse channels and send messages while offline.
  • Familiar behavior: The UI elements are good platform citizens and behave like native elements; they respect tintColor, layoutMargins, light/dark mode, dynamic font sizes, etc.
  • Swift native API: Uses Swift's powerful language features to make the SDK usage easy and type-safe.
  • Uses UIKit patterns and paradigms: The API follows the design of native system SDKs. It makes integration with your existing code easy and familiar.
  • SwiftUI support: We have developed a brand new SDK to help you have smoother Stream Chat integration in your SwiftUI apps.
  • First-class support for Combine: The StreamChat SDK (Low Level Client) has Combine wrappers to make it really easy use in an app that uses Combine.
  • Fully open-source implementation: You have access to the complete source code of the SDK here on GitHub.
  • Supports iOS 12+: We proudly support older versions of iOS, so your app can stay available to almost everyone.

Quick Links

  • iOS/Swift Chat Tutorial: Learn how to use the SDK by following our simple tutorial with UIKit (or SwiftUI).
  • Register: Register to get an API key for Stream Chat.
  • Installation: Learn more about how to install the SDK using CocoaPods, SPM or Carthage.
  • Documentation: An extensive documentation is available to help with you integration.
  • SwiftUI: Check our SwiftUI SDK if you are developing with SwiftUI.
  • Demo app: This repo includes a fully functional demo app with example usage of the SDK.
  • Example apps: This section of the repo includes fully functional sample apps that you can use as reference.

Free for Makers

Stream is free for most side and hobby projects. You can use Stream Chat for free if you have less than five team members and no more than $10,000 in monthly revenue.

Main Principles

  • Progressive disclosure: The SDK can be used easily with very minimal knowledge of it. As you become more familiar with it, you can dig deeper and start customizing it on all levels.

  • Highly customizable: Every element is designed to be easily customizable. You can modify the brand color by setting tintColor, apply appearance changes using custom UI rules, or subclass existing elements and inject them everywhere in the system, no matter how deep is the logic hierarchy.

  • open by default: Everything is open unless there's a strong reason for it to not be. This means you can easily modify almost every behavior of the SDK such that it fits your needs.

  • Good platform citizen: The UI elements behave like good platform citizens. They use existing iOS patterns; their behavior is predictable and matches system UI components; they respect tintColor, layourMargins, dynamic font sizes, and other system-defined UI constants.

Dependencies

This SDK tries to keep the list of external dependencies to a minimum. Starting 4.6.0, and in order to improve the developer experience, dependencies are hidden inside our libraries. (Does not apply to StreamChatSwiftUI's dependencies yet).

Learn more about our dependencies here

Using Objective-C

You can still integrate our SDKs if your project is using Objective-C. In that case, any customizations would need to be done by subclassing our components in Swift, and then use those directly from the Objective-C code.


We are hiring

We've recently closed a $38 million Series B funding round and we keep actively growing. Our APIs are used by more than a billion end-users, and you'll have a chance to make a huge impact on the product within a team of the strongest engineers all over the world. Check out our current openings and apply via Stream's website.


Quick Overview

Channel List

Features Preview
A list of channels matching provided query
Channel name and image based on the channel members or custom data
Unread messages indicator
Preview of the last message
Online indicator for avatars
Create new channel and start right away

Message List

Features Preview
A list of message in a channel
Photo preview
Message reactions
Message grouping based on the send time
Link preview
Inline replies
Message threads
GIPHY support

Message Composer

Features Preview
Support for multiline text, expands and shrinks as needed
Image and file attachments
Replies to messages
Tagging of users
Chat commands like mute, ban, giphy

Chat Commands

Features Preview
Easily search commands by writing / symbol or tap bolt icon
GIPHY support out of box
Supports mute, unmute, ban, unban commands
WIP support of custom commands

User Tagging Suggestion

Features Preview
User mentions preview
Easily search for concrete user
Mention as many users as you want

stream-chat-swift's People

Contributors

adamrushy avatar adolfogarza avatar b-onc avatar bielikb avatar buh avatar cardoso avatar daemonloki avatar dmigach avatar dominikbucher12 avatar evsaev avatar hugobernalstream avatar igorrosocha avatar ipavlidakis avatar jeroenleenarts avatar laevandus avatar lukasackee avatar mantergo avatar manwithbear avatar martinmitrevski avatar nuno-vieira avatar olejnjak avatar polqf avatar sagarsdagdu avatar skorepak avatar stream-ios-bot avatar tbarbugli avatar testableapple avatar tilton avatar tschellenbach avatar vojtastavik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stream-chat-swift's Issues

No ViewChanges.itemRemoved on delete channel

What did you do?

Delete channel with func deleteChannel() -> Observable<Void> (Channel+Requests.swift:79).

What did you expect to happen?

Channel is deleted and the ViewChanges.itemRemoved is send.

What happened instead?

Channel is deleted but no ViewChanges.itemRemoved is send.

GetStream Environment

GetStream Chat version: 1.3.3
iOS version: 12.4.1
Swift version: 4.2
Xcode version: 10.3
Device: iPhone X

Unable to get push notification

What did you do?

I just called your add device method with device token and it got every possible parameters
along with success .
Screenshot 2020-03-13 at 7 05 13 PM

What did you expect to happen?

Push Notification(s)

What happened instead?

No Push Notifications

GetStream Environment

GetStream Chat version: 1.5.7
**iOS version:**13.3
**Swift version:**5
**Xcode version:**11.3.1
**Device:**iPhone 7 Plus

Additional context

I debug and found that it is giving me successful device addition in terms of push notifications but still no push notifications no idea .
Screenshot 2020-03-13 at 6 56 52 PM
Screenshot 2020-03-13 at 6 51 42 PM

Composer view changes position if ChatViewController is not on very top of the screen

What did you do?

In our app ChatViewController is not always on very top of the screen. Because of that composer view gets too high.

What did you expect to happen?

I expect ComposerView to be always on the bottom of ChatViewController, no matter what's the position of view controller (when keyboard is closed)

What happened instead?

ComposerView moves around :D

Additional context

I created commit with animation to show the problem:
https://github.com/mpodeszwa/stream-chat-swift/commit/ff7f4bef7957bcdb571032423122887d32e2c371

And there is a gif πŸ˜‚

composer offset

Logout

Does sdk has logout to support multiple users?

Feature request: Filter for messages

I'm using GetStream for chat with customer service. I need to support messages visible only to the customer service agent on web but invisible to the user on ios (like internal messages from other services). I tried writing code like this:

    override func messageCell(at indexPath: IndexPath, message: Message, readUsers: [StreamChatCore.User]) -> UITableViewCell {
        let attachment = message.attachments.first(where: { $0.extraData?.data is ExtraAttachmentData })
        if attachment?.type == AttachmentType.custom(type: "notification"), let notification = (attachment?.extraData?.data as? ExtraAttachmentData)?.data {
            if notification.isHidden {
                return tableView.dequeueReusableCell(withType: ChatHiddenCell.self, for: indexPath)
            } else {
                let cell = tableView.dequeueReusableCell(withType: ChatNotificationCell.self, for: indexPath)
                cell.setup(notification: notification)
                return cell
            }
        }
        return super.messageCell(at: indexPath, message: message, readUsers: readUsers)
    }

ChatHiddenCell is just UITableViewCell with height 0, ChatNotificationCell is my custom cell for notifications presented to the user.
However there will be a problem with date cells showing above invisible messages.
Would it be possible to add filter to ChannelPresenter or ChatViewController so GetStream can ignore some messages and never add them to var items: [StreamChatCore.ChatItem]?

NSInternalInconsistencyException when updating ChatViewController

Framework crashed with error:

Fatal Exception: NSInternalInconsistencyException
Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (28), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).

Stacktrace:
chat update table crash.txt

We shipped app with GetStream at commit f2ab4e8

Fatal Exception: NSInternalInconsistencyException

Framework crashed on our app with following error:
Fatal Exception: NSInternalInconsistencyException

Invalid parameter not satisfying: formatOptions == 0 || !(formatOptions & ~(NSISO8601DateFormatWithYear | NSISO8601DateFormatWithMonth | NSISO8601DateFormatWithWeekOfYear | NSISO8601DateFormatWithDay | NSISO8601DateFormatWithTime | NSISO8601DateFormatWithTimeZone | NSISO8601DateFormatWithSpaceBetweenDateAndTime | NSISO8601DateFormatWithDashSeparatorInDate | NSISO8601DateFormatWithColonSeparatorInTime | NSISO8601DateFormatWithColonSeparatorInTimeZone | NSISO8601DateFormatWithFullDate | NSISO8601DateFormatWithFullTime | NSISO8601DateFormatWithInternetDateTime))
globalinit_33_4C19912DD841259A848CA079747E3591_func7

Stacktrace:
getstream crash.txt

We shipped app with GetStream at commit f2ab4e8

Channel.Config never gets updated

What did you do?

I'm creating ChannelPresenter using code:

let channel = Channel(type: type, id: id, name: name)
let channelPresenter = ChannelPresenter(channel: channel)

When first query succeeds framework is receiving response:

{
	"channel": {
                 ......
		"config": {
			"created_at": "2019-08-22T08:24:56.766147237Z",
			"updated_at": "2019-08-22T08:24:56.766147316Z",
			"name": "commerce",
			"typing_events": true,
			"read_events": true,
			"connect_events": true,
			"search": true,
			"reactions": true,
			"replies": true,
			"mutes": true,
			"message_retention": "infinite",
			"max_message_length": 5000,
			"automod": "disabled",
			"automod_behavior": "flag",
			"commands": [{
				"name": "flag",
				"description": "Flag a user",
				"args": "[@username]",
				"set": "moderation_set"
			}, {
				"name": "ban",
				"description": "Ban a user",
				"args": "[@username] [text]",
				"set": "moderation_set"
			}, {
				"name": "unban",
				"description": "Unban a user",
				"args": "[@username]",
				"set": "moderation_set"
			}, {
				"name": "mute",
				"description": "Mute a user",
				"args": "[@username]",
				"set": "moderation_set"
			}, {
				"name": "unmute",
				"description": "Unmute a user",
				"args": "[@username]",
				"set": "moderation_set"
			}]
		}
	},
        .......

What did you expect to happen?

I expect channel's config to change according to data received from backend.

Alternatively I need option to change config from the code (currently Config doesn't have public initializer and Channel's initializer doesn't accept config as a parameter).

What happened instead?

Config always stays with default values. I especially need readEventsEnabled to show number of unread messages on the badge (and mark messages as read)

GetStream Environment

GetStream Chat version: 1.2.8
iOS version: 12.4
Swift version: 5.0
Xcode version: 10.3
Device: Any device

StreamChat Roadmap

General discussion about the roadmap for the iOS library, let us know your thoughts.

  1. The low level client should be usable if you're not using RXSwift

How can I prevent users from deleting/editing their messages?

Hi,
we want to remove option for users to delete or edit their own messages. I found Permissions in chat settings and I configured it as on the screenshot below but users can still delete their messages. Are permissions implemented? :) Or is there another way to disable these functionalities?
Screenshot 2020-01-02 at 12 40 10

Add Attachment button is not visible

What did you do?

I'm creating chat view using code:

let channel = Channel(type: .commerce, id: channelId, name: channelName)
let channelPresenter = ChannelPresenter(channel: channel, showStatuses: true)
let chatView = ChatViewController()
chatView.channelPresenter = channelPresenter

When channel is created using this initializer it'll have default config:

Channel.swift:130
config = Config()

What did you expect to happen?

I expect add attachment button to appear once config is loaded (in initial request of loading messages)

What happened instead?

Composer view is lazily created once

open func createComposerAddFileContainerView(title: String) -> ComposerHelperContainerView? {
    guard let presenter = channelPresenter, presenter.channel.config.uploadsEnabled, !composerAddFileTypes.isEmpty else {
        return nil
    }
    ...
}

so when config is loaded composer view doesn't change

GetStream Environment

GetStream Chat version: 1.3.19

Question about usersRead of a message

We are trying to understand how to check if a message was read by a specific user.

Our app subscribes to the view changes of a channel and uses the items which are returned by ViewChanges.itemAdded - Then we iterate over every item (ChatItem) and cast it with case message(Message, _ usersRead: [User]) to a message and the list of users which should already read the message. Unfortunately the list is always empty.
The last_read in read on the channel JSON response shows a younger date then all messages in the channel, so as I understand it right now all messages should be seen as read but we never get a list of usersRead.

Could you explain how we can check if a user has read a message?

Race condition

What did you do?

I'm closing one ChatViewController (this bug doesn't happen on first entrance to ChatViewController). Later I'm creating new instance and I do following configurations:

  • I set Client.shared.setUser
  • I create ChannelPresenter
  • I add Client observations (onEvent)

If I do everything before websocket receives event message ChatViewController is stuck and messages will never be downloaded

GetStream Environment

I've created commit to reproduce this issue:

f3f201a

Note: I added delay to websocket response. I need it to reproduce issue on example app but it happens on my app without this delay.

Additional context

I did some investigation and framework's state looks like this:

As a side note I've fixed my app by adding observation for event .newMessages only once before setting user but I'm worried this race condition may show up in different situation.

ComposerView stuck behind keyboard when there's opaque TabBar

What did you do?

  1. Create tabBarController with opaque (non-translucent tabBar), embed a navigation stack + channelsViewController
  2. Open a chat
  3. Focus on composer view

What did you expect to happen?

ComposerView relocates itself when keyboard appears

What happened instead?

ComposerView got stuck behind keyboard

GetStream Environment

**GetStream Chat version:1.5.4
**iOS version:11, 12, 13
**Swift version:5.1
**Xcode version:11.3
**Device:All

Feature request: Custom attachments

Hi, I need to support custom attachments in my app. I found Attachment class here but it's not really sufficient for my case. I need more custom fields inside.

Is there a way to register my custom Attachment struct for a given attachment's type? Or is there any override point where I can add my custom type?

Feature request: Ability to disable mutes and flags

I can see mutes value comes from api in channel's config but it's not respected on the client:

		"config": {
			"created_at": "2019-08-22T08:24:56.766147237Z",
			"updated_at": "2019-08-22T08:24:56.766147316Z",
			"name": "commerce",
			"typing_events": true,
			"read_events": true,
			"connect_events": true,
			"search": true,
			"reactions": true,
			"replies": true,
			"mutes": true,
			"message_retention": "infinite",
			"max_message_length": 5000,
			"automod": "disabled",
			"automod_behavior": "flag",
		}

I couldn't find a way to disable flag feature using channel's config or presenter's variable.

Disabling muting is particularly important for us because we use GetStream as a chat with our customer service. We don't want user to have ability to mute Customer Service Agent.

Push Notifications: Device token registration

Hi guys,

we started to integrate push notification into our app based on StreamChatCore.

As far as I can see the SDK dosen't support register/unregister device token, right now. But I also saw that you already added a draft to Endpoint for add, remove and list of device tokens. I implemented the addDevice call to do some testing on our side which worked so far.

Could you give as a little bit more insights when do you plan to support register/unregister device tokens via the SDK?

Thx
Jan

ChatViewController marks messages as read even if it's not visible

What did you do?

I present ChatViewController in UITabBarController. If user is not on the chat tab I'm observing new messages using code:

        Client.shared.onEvent(.messageNew)
            .subscribe(onNext: { [weak self] event in
                if case let .messageNew(_, unread, _, _, _, _) = event {
                    self?.presenter.setBadge(unread)
                }
            })

What did you expect to happen?

I expect unread messages counter to increase with every new message and messages should be marked as read only after user enters the view. I can see code doing that:

    open override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        startGifsAnimations()
        markReadIfPossible()
    }

However there is this code in viewDidLoad which marks messages as read even if view controller is currently not visible:

        presenter.changes
            .filter { [weak self] _ in self?.changesEnabled ?? false }
            .do(onNext: { [weak self] _ in self?.markReadIfPossible() })
            .drive(onNext: { [weak self] in self?.updateTableView(with: $0) })
            .disposed(by: disposeBag)

What happened instead?

Every message received is immediately marked as read even though user is on another tab.

GetStream Environment

GetStream Chat version: 1.2.10

Crash on video upload > 20MB

What did you do?

I uploaded a video and app crashed. I see in logs, body size exceeded the limit (20M)

What did you expect to happen?

It should not crash instead should throw error , if possible before even upload begins.

What happened instead?

Crashed with

Thread 1: Fatal error: Binding error: responseError(StreamChatCore.ClientErrorResponse(code: 22, message: "body size exceeded the limit (20M)", statusCode: 400))


🐴 ⏫ [7] 32768/78055962, 0.0%
🐴 ⏫ [7] 65536/78055962, 0.0%
🐴 ⏫ [7] 98304/78055962, 0.0%
🐴 ⏫ [7] 131072/78055962, 0.0%
🐴 ⏫ [7] 163840/78055962, 0.0%
🐴 ⏫ [7] 229376/78055962, 0.0%
🐴 ⏱ Response received: 1.853 +1.853
🐴 ⬅️ Response 413 (95 bytes): https://chat-proxy-us-east.stream-io-api.com/channels/messaging/!members-HSeqPt/file?api_key=&user_id=&client_id=
🐴 πŸ“¦ {
  "code" : 22,
  "message" : "body size exceeded the limit (20M)",
  "StatusCode" : 400,
  "duration" : "0.00ms"
}

GetStream Environment

GetStream Chat version: Stream Chat v.1.5.4
iOS version: 13
Swift version: 5
Xcode version: 11.3.1
Device: iPhone 7

Members of a channel

I was trying to get the members of a channel. I found the members set on the Channel type but it seems to be always empty.

I tried to trace back the path how the members property of a Channel is set but couldn't find a way which is working. Unfortunately, the response from the API dosen't contains members on the level of a channel, if we fetch channels with a ChannelPresenter.

But, what I also discoverd was the members set on the ChannelPresenter type which is set by parsing a ChannelResponse in private func parseResponse(_ query: ChannelResponse) -> ViewChanges. Unfortunately the members property is not public so it can't be used outside of StreamChatCore.

My questions are:

  • Did I miss the correct way how to get/fill the members of a channel? If yes, how?
  • Or is this a misssing feature which will come in the future?

Why we need this?

  • We build a custom channels view controller where we present the members of a channel for every channel cell as subtitle

Crash when message is received while ChatViewController is inactive

What did you do?

  1. Open ChatViewController in UITabBar
  2. Move to different tab
  3. Receive new message
  4. Move back to ChatViewController
  5. Receive new message
  6. App crashes

What did you expect to happen?

No crash :D

What happened instead?

Crash πŸ€·β€β™‚

Additional context

2019-09-06 17:31:45.684197+0200 AHOYRC[16341:6943594] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete row 28 from section 0 which only contains 28 rows before the update'
*** First throw call stack:
(
	0   CoreFoundation                      0x000000011474a8db __exceptionPreprocess + 331
	1   libobjc.A.dylib                     0x0000000113cedac5 objc_exception_throw + 48
	2   CoreFoundation                      0x000000011474a662 +[NSException raise:format:arguments:] + 98
	3   Foundation                          0x000000010d8ab76b -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 194
	4   UIKitCore                           0x000000011cf18282 -[UITableView _endCellAnimationsWithContext:] + 4898
	5   UIKitCore                           0x000000011cf34941 -[UITableView _performBatchUpdates:withContext:completion:] + 253
	6   UIKitCore                           0x000000011cf34a2b -[UITableView performBatchUpdates:completion:] + 52
	7   StreamChat                          0x0000000112192654 $s10StreamChat0B14ViewControllerC011updateTableC033_B6716BA6282A64D555BE30E64C17210ALL4withy0aB4Core0C7ChangesO_tFyyXEfU_ + 388
	8   StreamChat                          0x00000001121949d0 $s10StreamChat0B14ViewControllerC011updateTableC033_B6716BA6282A64D555BE30E64C17210ALL4withy0aB4Core0C7ChangesO_tFyyXEfU_TA + 48
	9   StreamChat                          0x0000000112194901 $sIg_Ieg_TRTA + 17
	10  StreamChat                          0x0000000112194e39 $sIg_Ieg_TRTA.42 + 9
	11  StreamChat                          0x0000000112189a7e $sIeg_IyB_TR + 14
	12  UIKitCore                           0x000000011d1eaec1 +[UIView(Animation) performWithoutAnimation:] + 90
	13  StreamChat                          0x000000011218f5de $s10StreamChat0B14ViewControllerC011updateTableC033_B6716BA6282A64D555BE30E64C17210ALL4withy0aB4Core0C7ChangesO_tF + 4830
	14  StreamChat                          0x000000011218e2c2 $s10StreamChat0B14ViewControllerC11viewDidLoadyyFy0aB4Core0C7ChangesOcfU0_TA + 66
	15  StreamChat                          0x0000000112182f8a $s14StreamChatCore11ViewChangesOIegg_ACIegn_TR + 42
	16  StreamChat                          0x000000011218e2f1 $s14StreamChatCore11ViewChangesOIegg_ACIegn_TRTA + 17
	17  RxSwift                             0x00000001136a9dd5 $s7RxSwift14ObservableTypePAAE9subscribe6onNext0F5Error0F9Completed0F8DisposedAA10Disposable_py7ElementQzcSg_ys0H0_pcSgyycSgAOtFyAA5EventOyAKGcfU_ + 373
	18  RxSwift                             0x00000001136a9fd5 $s7RxSwift14ObservableTypePAAE9subscribe6onNext0F5Error0F9Completed0F8DisposedAA10Disposable_py7ElementQzcSg_ys0H0_pcSgyycSgAOtFyAA5EventOyAKGcfU_TA + 53
	19  RxSwift                             0x00000001136c3267 $s7RxSwift17AnonymousObserverC6onCoreyyAA5EventOyxGF + 39
	20  RxSwift                             0x00000001136ab823 $s7RxSwift12ObserverBaseC2onyyAA5EventOyxGF + 227
	21  RxSwift                             0x00000001136aba42 $s7RxSwift12ObserverBaseCyxGAA0C4TypeA2aEP2onyyAA5EventOy7ElementQzGFTW + 18
	22  RxSwift                             0x000000011371f943 $sTA + 67
	23  RxSwift                             0x000000011369b3bc $s7RxSwift5EventOyxGIegn_ADytIegnr_7ElementQyd__RszAA12ObserverTypeRd__r__lTR + 12
	24  RxSwift                             0x000000011371676d $s7RxSwift5EventOyxGIegn_ADytIegnr_7ElementQyd__RszAA12ObserverTypeRd__r__lTRTA + 29
	25  RxSwift                             0x00000001137167b9 $s7RxSwift5EventOyxGIegn_ADytIegnr_7ElementQyd__RszAA12ObserverTypeRd__r__lTRTA.13 + 9
	26  RxSwift                             0x000000011371556d $s7RxSwift36ShareReplay1WhileConnectedConnection33_E9FE621655D67A613BF2FC2D9B3041FCLLC2onyyAA5EventOyxGFTm + 109
	27  RxSwift                             0x0000000113715007 $s7RxSwift36ShareReplay1WhileConnectedConnection33_E9FE621655D67A613BF2FC2D9B3041FCLLCyxGAA12ObserverTypeA2aFP2onyyAA5EventOy7ElementQzGFTW + 23
	28  RxSwift                             0x00000001136c1ee3 $s7RxSwift4SinkC9forwardOnyyAA5EventOy7ElementQzGF + 99
	29  RxSwift                             0x00000001136828d3 $s7RxSwift10FilterSink33_172A575932639FDD42969ED91F7BE949LLC2onyyAA5EventOy7ElementQzGF + 451
	30  RxSwift                             0x0000000113682a40 $s7RxSwift10FilterSink33_172A575932639FDD42969ED91F7BE949LLCyxGAA12ObserverTypeA2aFP2onyyAA5EventOy7ElementQzGFTW + 16
	31  RxSwift                             0x000000011371f943 $sTA + 67
	32  RxSwift                             0x000000011369b3bc $s7RxSwift5EventOyxGIegn_ADytIegnr_7ElementQyd__RszAA12ObserverTypeRd__r__lTR + 12
	33  RxSwift                             0x000000011371676d $s7RxSwift5EventOyxGIegn_ADytIegnr_7ElementQyd__RszAA12ObserverTypeRd__r__lTRTA + 29
	34  RxSwift                             0x00000001137167b9 $s7RxSwift5EventOyxGIegn_ADytIegnr_7ElementQyd__RszAA12ObserverTypeRd__r__lTRTA.13 + 9
	35  RxSwift                             0x000000011371556d $s7RxSwift36ShareReplay1WhileConnectedConnection33_E9FE621655D67A613BF2FC2D9B3041FCLLC2onyyAA5EventOyxGFTm + 109
	36  RxSwift                             0x0000000113715007 $s7RxSwift36ShareReplay1WhileConnectedConnection33_E9FE621655D67A613BF2FC2D9B3041FCLLCyxGAA12ObserverTypeA2aFP2onyyAA5EventOy7ElementQzGFTW + 23
	37  RxSwift                             0x00000001136c1ee3 $s7RxSwift4SinkC9forwardOnyyAA5EventOy7ElementQzGF + 99
	38  RxSwift                             0x00000001136d0e76 $s7RxSwift13MergeSinkIter33_DDEA0423368B3B462AE46699A4D080E1LLC2onyyAA5EventOy7ElementQy_GF + 422
	39  RxSwift                             0x00000001136d0f70 $s7RxSwift13MergeSinkIter33_DDEA0423368B3B462AE46699A4D080E1LLCyxq_q0_GAA12ObserverTypeA2aFP2onyyAA5EventOy7ElementQzGFTW + 16
	40  RxSwift                             0x000000011371f943 $sTA + 67
	41  RxSwift                             0x000000011369b3bc $s7RxSwift5EventOyxGIegn_ADytIegnr_7ElementQyd__RszAA12ObserverTypeRd__r__lTR + 12
	42  RxSwift                             0x000000011371676d $s7RxSwift5EventOyxGIegn_ADytIegnr_7ElementQyd__RszAA12ObserverTypeRd__r__lTRTA + 29
	43  RxSwift                             0x00000001137167b9 $s7RxSwift5EventOyxGIegn_ADytIegnr_7ElementQyd__RszAA12ObserverTypeRd__r__lTRTA.13 + 9
	44  RxSwift                             0x000000011371556d $s7RxSwift36ShareReplay1WhileConnectedConnection33_E9FE621655D67A613BF2FC2D9B3041FCLLC2onyyAA5EventOyxGFTm + 109
	45  RxSwift                             0x0000000113715007 $s7RxSwift36ShareReplay1WhileConnectedConnection33_E9FE621655D67A613BF2FC2D9B3041FCLLCyxGAA12ObserverTypeA2aFP2onyyAA5EventOy7ElementQzGFTW + 23
	46  RxSwift                             0x00000001136c1ee3 $s7RxSwift4SinkC9forwardOnyyAA5EventOy7ElementQzGF + 99
	47  RxSwift                             0x00000001136acb77 $s7RxSwift9CatchSink33_7E15DB08AB19A7B882D5C92A393C6F6DLLC2onyyAA5EventOy7ElementQzGF + 375
	48  RxSwift                             0x00000001136aceb0 $s7RxSwift9CatchSink33_7E15DB08AB19A7B882D5C92A393C6F6DLLCyxGAA12ObserverTypeA2aFP2onyyAA5EventOy7ElementQzGFTW + 16
	49  RxSwift                             0x00000001137254a5 $s7RxSwift32ObserveOnSerialDispatchQueueSink33_277A93ABA8477198C125F3F26B2D4B62LLC9scheduler8observer6cancelADyxGAA0efG9SchedulerC_xAA10Cancelable_ptcfcAA10Disposable_pAH4sink_AA5EventOy7ElementQzG5eventt_tcfU_ + 437
	50  RxSwift                             0x0000000113725cec $s7RxSwift32ObserveOnSerialDispatchQueueSink33_277A93ABA8477198C125F3F26B2D4B62LLC9scheduler8observer6cancelADyxGAA0efG9SchedulerC_xAA10Cancelable_ptcfcAA10Disposable_pAH4sink_AA5EventOy7ElementQzG5eventt_tcfU_TA + 12
	51  RxSwift                             0x0000000113725c8a $s7RxSwift32ObserveOnSerialDispatchQueueSink33_277A93ABA8477198C125F3F26B2D4B62LLCyxGAA5EventOy7ElementQzGAA10Disposable_pIeggnr_AE_AJtAaK_pIegnr_AA12ObserverTypeRzlTRTA + 154
	52  RxSwift                             0x000000011369e821 $s7RxSwift13MainSchedulerC16scheduleInternal_6actionAA10Disposable_px_AaF_pxctlFyycfU_ + 113
	53  RxSwift                             0x000000011369ea51 $s7RxSwift13MainSchedulerC16scheduleInternal_6actionAA10Disposable_px_AaF_pxctlFyycfU_TA + 33
	54  RxSwift                             0x00000001136929d0 $sIeg_IeyB_TR + 32
	55  libdispatch.dylib                   0x000000011589fd7f _dispatch_call_block_and_release + 12
	56  libdispatch.dylib                   0x00000001158a0db5 _dispatch_client_callout + 8
	57  libdispatch.dylib                   0x00000001158ae080 _dispatch_main_queue_callback_4CF + 1540
	58  CoreFoundation                      0x00000001146b1a79 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
	59  CoreFoundation                      0x00000001146ac126 __CFRunLoopRun + 2310
	60  CoreFoundation                      0x00000001146ab4d2 CFRunLoopRunSpecific + 626
	61  GraphicsServices                    0x00000001171902fe GSEventRunModal + 65
	62  UIKitCore                           0x000000011cd19fc2 UIApplicationMain + 140

I fixed it by adding this code but I think it should be in the framework :)

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        refreshTableView(scrollToBottom: true, animated: false)
    }

Unable to get push notification

What did you do?

  1. Open the app.
  2. Allowed pushed via permission pop up.
  3. Closed the app.
  4. Waited for 5 mins (so client get disconnected #31 (comment) )
  5. Sent the message from another device.

What did you expect to happen?

I was expecting a push notification

What happened instead?

Didn't get any push

GetStream Environment

GetStream Chat version: 1.5.4
iOS version: 13.3
Swift version: 5
Xcode version: 11.3.1
Device: iPhone x

Additional context

I was using different keys but didn't get any push so I tried using the different keys.
But no luck.
On stream dashboard under push logs it says
publishing the message failed with error: InvalidProviderToken

On log details I found the push token and I was able to send push using that token using a push test utility I found on web.

New messages aren't grouped correctly

What did you do?

  • Create a channel
  • Send a message
  • Wait one day (literally)
  • Send a new message

What did you expect to happen?

  • a status "Today" to appear between my last message (sent yesterday) and new message (sent today)

What happened instead?

  • No status, messages are grouped
  • After restarting the app, status appears as expected

GetStream Environment

GetStream Chat version:1.5.4
iOS version:All
Swift version:All
Xcode version:All
Device:All

Make `version` public

Just a proposal for improvement, make static let version: String (Client+Request.swift:12) public. This would help to identify at runtime which version of stream-chat is used.

For example, we use this in crash reports and also for user support requests. Would make our life a little bit easier 🀩

CIS-21 Send messages with image/video attachments without waiting for upload

What are you trying to achieve?

Send message with image/video attachment

If possible, how can you achieve this currently?

Wait for the upload to end

What would be the better way?

Send the message and then upload (like whatsapp)

GetStream Environment

GetStream Chat version:1.5.5
iOS version:All
Swift version:All
Xcode version:All
Device:All

CIS-42 Support markdown for links

What are you trying to achieve?

Get [link](www.url.com) to render in markdown (as link)

If possible, how can you achieve this currently?

None

What would be the better way?

None

GetStream Environment

GetStream Chat version:1.5.6
iOS version:All
Swift version:All
Xcode version:All
Device:All

Additional context

A Web Socket connection id is empty. Authorization missed

Occasionally our users get an error "A Web Socket connection id is empty. Authorization missed". Usually it happens right after application is becoming active (after being in background), sometimes up to 20 seconds after becoming active. Do you know what may be happening?

GetStream Environment

GetStream Chat commit: ad9e3c8
iOS version: 13.3
Swift version: 5.1
Xcode version: 11.3.1
Device: iPhone XS

(device and ios version from sample report)

Composer is not visible if ChatViewController is offset from the top

What did you do?

On my application ChatViewController doesn't start from the top, it has offset.

What did you expect to happen?

When keyboard appears composer should move up so user can see his message while typing

What happened instead?

Composer is under keyboard, user can't see textfield when keyboard is open

Additional context

I created branch to show the problem:
https://github.com/mpodeszwa/stream-chat-swift/commits/demo/vc-offset

Simulator Screen Shot - iPhone Xs - 2019-09-02 at 15 10 27

Simulator Screen Shot - iPhone Xs - 2019-09-02 at 15 15 21

Uploaded videos are not clickable

What did you do?

  1. Upload video on any chat
  2. Click on video

What did you expect to happen?

A preview/webview to open for viewing video

What happened instead?

Only reactionsView shows

GetStream Environment

**GetStream Chat version:1.5.3
**iOS version:All
**Swift version:5.1
**Xcode version:11.3
**Device:All

CIS-24 Channel unreadCount isn't updated when a message is deleted

What did you do?

  1. Send a message from user 1
  2. Observe channel unreadCount from user 2
  3. Delete the message from user 1

What did you expect to happen?

unreadCount to reflect current state

What happened instead?

It still registers deletedMessage as unread

GetStream Environment

GetStream Chat version:1.5.5
iOS version:All
Swift version:All
Xcode version:All
Device:All

CIS-27 SPM support

Hi,
Soon we will be moving away from Pods and Carthage to SPM. Could you provide Package.swift file to support importing GetStream using Swift Package Manager?

Can not view video

What did you do?

I uploaded the small video from camera, on 1.5.4 it shows reaction view and on 1.5.5 it crashes

What did you expect to happen?

View video on taping link.

What happened instead?

Crashes when I tap video.

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

GetStream Environment

GetStream Chat version: 1.5.5
iOS version: iOS 12
Swift version: 5
Xcode version: 11.3.1
Device:

Additional context

Logs from Xcode console

stream-chat-swift/Sources/UI/Web View/WebViewController.swift: 155: 19: Fatal error: Use of unimplemented initializer 'init(nibName:bundle:)' for class 'StreamChat.WebViewNavigationController'
2020-01-30 17:46:03.070103+0530 ChatExample[10610:205186] 
stream-chat-swift/Sources/UI/Web View/WebViewController.swift: 155: 19: Fatal error: Use of unimplemented initializer 'init(nibName:bundle:)' for class 'StreamChat.WebViewNavigationController'

Composer View misplaced everytime keyboard is shown

What did you do?

  • Installed the SDK via Carthage (also tried with CocoaPods) into my project
  • Opened the app
  • Created a channel
  • Tapped on the Composer View
  • Once the keyboard is shown, there's a weird gap in between Composer View and keyboard

What did you expect to happen?

Composer View should appear right on top of the Keyboard, no gaps should be displayed

What happened instead?

Strange gap appeared in between keyboard and Composer View. See resources below.
https://pasteboard.co/ISJs66E.png
https://drive.google.com/file/d/1DAKaQ50DBbgwZCI_d4b08d2ztaD98p78/view?usp=sharing

GetStream Environment

GetStream Chat version: 1.5.5
iOS version: 13.3
Swift version: 5.2.1
Xcode version: 11.2.1 (11B500)
Device: All devices

Additional context

If you guys do not have the time for solving this soon, I would like to hear any insight you can provide on how could it be solved, and then I can try to do so, if it works I'd love to open the PR.

Any help would be much appreciated!

PS: I have also read other issues such as #28 and #36 and it seems like it is still happening.

I can also say: my ChatViewController is embedded on a TabBarController if that helps.

Links in the message are not tappable when reactions are disabled

What did you do?

In my config reactions are disabled and I receive message with link inside.

What did you expect to happen?

I expect links inside message to work.

What happened instead?

When I tap on link nothing happens.

GetStream Environment

GetStream Chat version: 1.5.1

Additional context

Most probably it's because of this code:

        cell.messageStackView.rx.anyGesture(presenter.channel.config.reactionsEnabled
            ? [TapControlEvent.default, LongPressControlEvent.default]
            : [LongPressControlEvent.default])
            .subscribe(onNext: { [weak self, weak cell] gesture in
                if let self = self, let cell = cell {
                    if let tapGesture = gesture as? UITapGestureRecognizer {
                        self.handelMessageCellTap(from: cell, in: message, tapGesture: tapGesture)
                    } else {
                        self.showMenu(from: cell, for: message, locationInView: gesture.location(in: cell))
                    }
                }
            })
            .disposed(by: cell.disposeBag)

when reactions are disabled, tap gesture recognizer is not handled.

Crash when presenting UIDocumentMenuViewController inside web view

What did you do?

  • I've received message containing link to https://ahoy.io/getpassbook/
  • I clicked on the link and chat presented webview
  • I clicked on button "Select file" (it's a file picker)
  • App crashed with exception:
Your application has presented a UIDocumentMenuViewController (<UIDocumentMenuViewController: 0x154bc92b0>). In its current trait environment, the modalPresentationStyle of a UIDocumentMenuViewController with this style is UIModalPresentationPopover. You must provide location information for this popover through the view controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem.  If this information is not known when you present the view controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.

What did you expect to happen?

No crash :)

What happened instead?

It crashes on iPhone 11 Pro Max (iOS 13.3), doesn't crash on iPhone 5s (iOS 12.4). I didn't check more devices.

GetStream Environment

GetStream Chat commit: ad9e3c8
iOS version: 13.3
Swift version: 5.1
Xcode version: 11.3.1
Device: iPhone 11 Pro Max

CIS-40 Automize release process with fastlane

I’ve checked how we can create a fastlane lane for our release flow, I’m dumping my findings here:
each step corresponds to the steps from releasing.md:

  1. , 2. increment_version_number(version_number: <input>) https://docs.fastlane.tools/actions/increment_version_number/
  2. version_bump_podspec(path: <podspec>, version_number: <input>) https://docs.fastlane.tools/actions/version_bump_podspec/
  3. , 5. git_add , add_git_tag(tag: <input>), git_commit, push_to_git_remote(tags: true) https://docs.fastlane.tools/actions/
  4. , 7. jazzy https://docs.fastlane.tools/actions/jazzy/
  5. git_add, git_commit, push_to_git_remote
  6. this is a bit tricky. I’m considering adding a latest_release_notes.md file, which we’ll change for each release, and make fastlane parse this file’s contents, append it to CHANGELOG.md and also use the contents for github release: set_github_release https://docs.fastlane.tools/actions/set_github_release/
  7. pod_push https://docs.fastlane.tools/actions/pod_push/
    obviously we can remove step 8 by moving the steps 6 and 7 up 1 step.

StreamChat framework contains nested framework StreamChatCore when using Carthage

What did you do?

I updated StreamChat to version 1.5.6 using Carthage. When I tried uploading build to the appstore I got following error:

2020-02-14 12:23:10.549 altool[88113:33733047] ERROR ITMS-90205: "Invalid Bundle. The bundle at '.app/Frameworks/StreamChat.framework' contains disallowed nested bundles."
2020-02-14 12:23:10.549 altool[88113:33733047] ERROR ITMS-90206: "Invalid Bundle. The bundle at '.app/Frameworks/StreamChat.framework' contains disallowed file 'Frameworks'.

After investigating closer I found out StreamChat.framework contains StreamChatCore.framework inside:

~> tree StreamChat.framework
StreamChat.framework
β”œβ”€β”€ Assets.car
β”œβ”€β”€ Frameworks
β”‚Β Β  └── StreamChatCore.framework
β”‚Β Β      β”œβ”€β”€ Info.plist
β”‚Β Β      └── StreamChatCore
β”œβ”€β”€ Headers
β”‚Β Β  β”œβ”€β”€ StreamChat-Swift.h
β”‚Β Β  └── StreamChat.h
β”œβ”€β”€ Info.plist
β”œβ”€β”€ Modules
β”‚Β Β  β”œβ”€β”€ StreamChat.swiftmodule
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ arm64-apple-ios.swiftdoc
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ arm64-apple-ios.swiftmodule
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ arm64.swiftdoc
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ arm64.swiftmodule
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ x86_64-apple-ios-simulator.swiftdoc
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ x86_64-apple-ios-simulator.swiftmodule
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ x86_64.swiftdoc
β”‚Β Β  β”‚Β Β  └── x86_64.swiftmodule
β”‚Β Β  └── module.modulemap
└── StreamChat

5 directories, 16 files

What did you expect to happen?

StreamChat.framework shouldn't contain StreamChatCore.framework. It should be included by the apps integrating the library.

What happened instead?

StreamChat.framework contains StreamChatCore.framework and altool rejects the build before submitting

GetStream Environment

GetStream Chat version: 1.5.6
Xcode version: 11.3.1
Carthage version: 0.34.0

Additional context

It was fine at commit ad9e3c8 .
To reproduce just build StreamChat using carthage

Using ChatViewController second time doesn't work

What did you do?

I created ChatViewController using code:

channelPresenter = ChannelPresenter(channel: channel)
channelPresenter?.reload()

Chat is being presented to the user after logging in to the application. When user enters the app chat is working properly. However, when he logs out and logs back in (to the same account or a different one) chat is not loading.

What did you expect to happen?

Chat is working every time.

What happened instead?

Second ChatViewController never gets refreshed

GetStream Environment

GetStream Chat version: 1.2.5
iOS version: 12.4
Swift version: 5.0.1
Xcode version: 10.3
Device: iPhone Xs

Additional context

There are some logs.

First time ChatViewController is created:

πŸ“±  App state active
πŸ•Έ  Available πŸ™‹β€β™‚οΈ
🐴 [27/08/2019 11:36:58.812] 🎫 Skip read.
πŸ¦„ [27/08/2019 11:36:59.075] ❀️ Connecting...
πŸ¦„ [27/08/2019 11:36:59.075] ➑️ GET wss://chat-us-east-1.stream-io-api.com/connect?......&stream-auth-type=jwt
πŸ¦„ [27/08/2019 11:36:59.076] Request headers:
◾️ Origin = wss://chat-us-east-1.stream-io-api.com

πŸ¦„ [27/08/2019 11:37:00.342] WebSocket connected. Waiting for the first health check message...
πŸ¦„ [27/08/2019 11:37:00.402] πŸ“¦ {
  "created_at" : "2019-08-27T09:37:00.28453431Z",
  ....
}
πŸ¦„ [27/08/2019 11:37:00.405] πŸ₯° Connected

.... more responses

Logging out:

πŸ¦„ [27/08/2019 11:37:06.995] πŸ’” Disconnected deliberately

Logging back in to the same account (same channel id, different instances of ChatViewController and ChatPresenter):

πŸ“±  App state active
πŸ•Έ  Available πŸ™‹β€β™‚οΈ
🐴 [27/08/2019 11:37:19.012] 🎫 Skip read.
πŸ¦„ [27/08/2019 11:37:19.018] ❀️ Connecting...
πŸ¦„ [27/08/2019 11:37:19.019] ➑️ GET wss://chat-us-east-1.stream-io-api.com/connect?....&stream-auth-type=jwt
πŸ¦„ [27/08/2019 11:37:19.019] Request headers:
◾️ Origin = wss://chat-us-east-1.stream-io-api.com

🐴 [27/08/2019 11:37:19.059] 🎫 Skip read.

Additional info:

There are no memory leaks, however I can see instances of following types still existing after logging out:

Client
ClientURLSessionTaskDelegate
InternetConnection
WebSocket

Clear message history with hide doesn't appear to work

What did you do?

I called:
self.channelsPresenter.hide(channelPresenter, clearHistory: true).drive().disposed(by: self.disposeBag)

like in the example code.

What did you expect to happen?

I expected it to hide the channel and clear the message history

What happened instead?

It hid the channel, but when a new message was sent on the channel, the entire message history came back for this user... it wasn't cleared.

GetStream Environment

GetStream Chat version:
1.5.4

iOS version:
13.3

Swift version:
5

Xcode version:
11.3

Device:
iPhone 8 plus

Additional context

Channel type is "messaging" for watch requests

What did you do?

Context

  • One channel with type "team"
  • One channel with type "messaging"

Steps

1.) Start app
2.) Fetch channels for type "team" via ChannelsPresenter
3.) Fetch channels for type "messaging" via ChannelsPresenter
4.) SDK starts watching on a "team" channel

What did you expect to happen?

The channel with type "team" is not visible all channels with type "messaging".

What happened instead?

The channel with type "team" is duplicated and the new channel gets the type "messaging".

I did a little debugging and found out that the SDK always tries to watch a channel based on the channel_id and the default type "messaging" (Channel.swift:88), see ChannelPresenter.swift:99 and Client+Event.swift:36.

This causes the watch request (POST) to create a new channel for the given channel_id with type "messaging" because there is no channel with messaging:channel_id only a channel for the cid team:channel_id.

GetStream Environment

**GetStream Chat version: 1.3.0 **

Crash on image upload

What did you do?

I am using an example app , when I take photo from camera , it crashes because of network connectivity.

What did you expect to happen?

It should stop uploading image and should throw error instead of crashing.
It would be great on such occasions if it would show restart button and resume upload. But nevertheless even if it doesn't crash that will be great.

What happened instead?

Thread 1: Fatal error: Binding error: requestFailed(Optional(Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSUnderlyingError=0x282a74ae0 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x2806d4d20 [0x201a835e0]>{length = 16, capacity = 16, bytes = 0x100201bb3447a0070000000000000000}, _kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=https://chat-proxy-us-east.stream-io-api.com/channels/messagin

GetStream Environment

GetStream Chat version: Stream Chat v.1.5.4
iOS version: 13
Swift version: 5
Xcode version: 11.3
Device: iPhone7

Additional context

Logs from Xcode Console

🐴 Endpoint: sendEvent(StreamChatCore.EventType.typingStart, StreamChatCore.Channel)
🐴 ⏱ Sending request...
🐴 ➑️ POST https://chat-proxy-us-east.stream-io-api.com/channels/messaging/!members-HSeqPtTUswzmZdAvRk9eJHwRPonhXN0l8n_Esj7kFBQ/event?api_key=&user_id=&client_id=
🐴 πŸ“¦ Request Body {
  "event" : {
    "type" : "typing.start"
  }
}
🐴 ⏫ [8] 262144/1100317, 24.0%
🐴 ⏱ Response received: 0.274 +0.274
🐴 πŸ™…β€β™‚οΈ A request was cancelled. NSError -999
2020-01-30 12:07:39.964136+0530 Werq Chat[342:16137] Task <25D723B0-D5A0-4CF9-B173-20B599048477>.<9> finished with error [-999] Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLStringKey=https://chat-proxy-us-east.stream-io-api.com/channels/messaging/!members-HSeqPtTUswzmZdAvRk9eJHwRPonhXN0l8n_Esj7kFBQ/event?api_key=&user_id=&client_id=, NSLocalizedDescription=cancelled, NSErrorFailingURLKey=https://chat-proxy-us-east.stream-io-api.com/channels/messaging/!members-HSeqPtTUswzmZdAvRk9eJHwRPonhXN0l8n_Esj7kFBQ/event?api_key=&user_id=&client_id=}
2020-01-30 12:07:39.969929+0530 Werq Chat[342:16478] Task <25D723B0-D5A0-4CF9-B173-20B599048477>.<9> HTTP load failed, 0/0 bytes (error code: -999 [1:89])
🐴 ⏫ [8] 294912/1100317, 27.0%
🐴 ⏫ [8] 327680/1100317, 30.0%
🐴 ⏫ [8] 360448/1100317, 33.0%
🐴 ⏫ [8] 393216/1100317, 36.0%
🐴 ⏫ [8] 425984/1100317, 39.0%
🐴 ⏫ [8] 458752/1100317, 42.0%
🐴 ⏫ [8] 491520/1100317, 45.0%
🐴 ⏫ [8] 524288/1100317, 48.0%
🐴 ⏫ [8] 557056/1100317, 51.0%
🐴 ⏫ [8] 589824/1100317, 54.0%
🐴 ⏫ [8] 622592/1100317, 57.0%
🐴 ⏫ [8] 655360/1100317, 60.0%
🐴 ⏫ [8] 688128/1100317, 63.0%
🐴 ⏫ [8] 720896/1100317, 66.0%
🐴 ⏫ [8] 753664/1100317, 68.0%
🐴 ⏫ [8] 786432/1100317, 71.0%
🐴 ⏫ [8] 819200/1100317, 74.0%
🐴 ⏫ [8] 851968/1100317, 77.0%
🐴 ⏱ Response received: 6.676 +6.402
🐴 πŸ€·β€β™‚οΈ The network connection was lost. NSError -1005
2020-01-30 12:07:46.365473+0530 Werq Chat[342:16478] Task <EA09EE84-E4C8-48D3-B646-145436E86B33>.<8> HTTP load failed, 852714/0 bytes (error code: -1005 [4:-4])
2020-01-30 12:07:46.366247+0530 Werq Chat[342:16121] Task <EA09EE84-E4C8-48D3-B646-145436E86B33>.<8> finished with error [-1005] Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSUnderlyingError=0x282a74ae0 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x2806d4d20 [0x201a835e0]>{length = 16, capacity = 16, bytes = 0x100201bb3447a0070000000000000000}, _kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=https://chat-proxy-us-east.stream-io-api.com/channels/messaging/!members-HSeqPtTUswzmZdAvRk9eJHwRPonhXN0l8n_Esj7kFBQ/image?api_key=&user_id=&client_id=, NSErrorFailingURLKey=https://chat-proxy-us-east.stream-io-api.com/channels/messaging/!members-HSeqPtTUswzmZdAvRk9eJHwRPonhXN0l8n_Esj7kFBQ/image?api_key=&user_id=&client_id=, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-4, NSLocalizedDescription=The network connection was lost.}
🐴 ❌  Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSUnderlyingError=0x282a74ae0 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x2806d4d20 [0x201a835e0]>{length = 16, capacity = 16, bytes = 0x100201bb3447a0070000000000000000}, _kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=https://chat-proxy-us-east.stream-io-api.com/channels/messaging/!members-HSeqPtTUswzmZdAvRk9eJHwRPonhXN0l8n_Esj7kFBQ/image?api_key=&user_id=&client_id=, NSErrorFailingURLKey=https://chat-proxy-us-east.stream-io-api.com/channels/messaging/!members-HSeqPtTUswzmZdAvRk9eJHwRPonhXN0l8n_Esj7kFBQ/image?api_key=&user_id=&client_id=, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-4, NSLocalizedDescription=The network connection was lost.} in parse(data:response:error:completion:)[255]
(lldb) 

StatusTableViewCell customization

Is it possible to change the color of the text in the StatusTableViewCell.swift file? The file is declared final only so it's impossible to do an extension and add a custom method that allows the customization of the cell. Is there a way to do so?

Capture d’écran 2019-11-13 aΜ€ 19 11 52

Push Notifications not working with iOS 13

What did you do?

Sent messages to an iOS 13 device

What did you expect to happen?

Receive a push notification and for channelsViewController to update the channel cells with the latest messages

What happened instead?

No push notification in or out of the app, and channelsViewController stays stale with old messages until you restart the app

GetStream Environment

GetStream Chat version: stream-chat v1.1.4, StreamChatCore v1.3.20
iOS version: 13.1.2
Swift version: 5
Xcode version: 11.0
Device: iPhone X

Additional context

Observed push notifications behaving correctly on iOS 11/12 with same environment. Apple recently added a new attribute to the headers for APNS Headers, apns-push-type, which is required in iOS 13. https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns?language=objc

Query request to set presence state adds duplicated member

What did you do?

  • We have a channel with two users where the current user is a member
  • If we enter the channel to subscribe messages, the presence state will be set by SDK via the query call

What did you expect to happen?

  • The query call changes only the presence state

What happened instead?

  • The presence state is changed
  • The SDK adds also a duplicate to the members set of the channel

Which will result in an empty channel on the next try because of the failed query HTTP call which returns the following error message:

{
	"code": 4,
	"message": "GetOrCreateChannel failed with error: \"Duplicate members passed to get or create channel, only send 1 member once\"",
	"StatusCode": 400,
	"duration": "0.00ms"
}

GetStream Environment

GetStream Chat version: 1.3.2

Additional context

We tried to trace back the issue and found out that the code at Channel+Requests.swift:23

if let user = User.current {
  members.insert(user.asMember)
}

adds the duplicate. This is confusing because it should be a set and ignore users with the same identity. So, we checked the equality operator on the member type, see Member.swift:72.

public static func == (lhs: Member, rhs: Member) -> Bool {
  return lhs.user == rhs.user
    && lhs.created == rhs.created
    && lhs.updated == rhs.updated
}

Besides the identity of the user the function also checks for dates which are different for the User.current than the orignial user because they are initialize with the current date, see User.swift:99

created = .default
updated = .default

The initializer of the user type is used to do the intial setup with Client.shared.set(user:token:)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.