GetStream / stream-chat-swift

💬 iOS Chat SDK in Swift - Build your own app chat experience for iOS using the official Stream Chat API
https://getstream.io/chat/sdk/ios/
Other
858 stars 211 forks source link

Two separate ChatChannelListController mix results of each other #2092

Closed vadimue closed 2 years ago

vadimue commented 2 years ago

What did you do?

I've created two separate ChatChannelListVC with different queries and filters

What did you expect to happen?

I expect a different set of channels independent of each other.

What happened instead?

  1. Open First ChatChannelListVC
  2. First ChatChannelListVC has received a proper list of channels
  3. Open second ChatChannelListVC
  4. Second ChatChannelListVC has received a proper list of channels
  5. Open First ChatChannelListVC again
  6. First ChatChannelListVC contains a mix of channels from first and second queries

GetStream Environment

GetStream Chat version: 4.16.0 GetStream Chat frameworks: StreamChat, StreamChatUI iOS version: iOS 15.2 Swift version: Swift 5 Xcode version: Xcode 13.2.1 Device: iPhone 13 Simulator

Additional context

import UIKit
import StreamChat
import StreamChatUI

extension ChatClient {
    static let shared: ChatClient = {
        // You can grab your API Key from https://getstream.io/dashboard/
        var config = ChatClientConfig(apiKeyString: "armdvhqumfhe")
        // Create an instance of the `ChatClient` with the given config
        let client = ChatClient(config: config)

        return client
    }()
}

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = scene as? UIWindowScene else {
            return
        }

        let nonExpiringToken: Token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiUGF1bCJ9.8wAMYb4OCQauOH3jO5uTxrGvigGWKY5Pc60pac1jdlY"

        let userId = "Paul"
        // Create the user info to connect with
        let userInfo = UserInfo(
            id: userId,
            name: "Paul",
            imageURL: URL(string: "https://cutt.ly/SmeFRfC")
        )

        // Connect the client with the static token
        ChatClient.shared.connectUser(userInfo: userInfo, token: nonExpiringToken) { error in
         /* handle the connection error */
        }

        let query = ChannelListQuery(filter: .equal(.cid, to: try! ChannelId(cid: "messaging:Secret-Chat")))
        let controller = ChatClient.shared.channelListController(query: query)
        let channelListVC = ChatChannelListVC.make(with: controller)
        let channelListNVC = UINavigationController(rootViewController: channelListVC)

        let query2 = ChannelListQuery(filter: .equal(.cid, to: try! ChannelId(cid: "messaging:Common")))
        let controller2 = ChatClient.shared.channelListController(query: query2)
        let channelListVC2 = ChatChannelListVC.make(with: controller2)
        let channelListNVC2 = UINavigationController(rootViewController: channelListVC2)

        let windowObject = UIWindow(windowScene: windowScene)
        window = windowObject
        let tabBar = UITabBarController()
        tabBar.viewControllers = [channelListNVC, channelListNVC2]
        window?.rootViewController = tabBar
        window?.makeKeyAndVisible()

        guard let _ = (scene as? UIWindowScene) else { return }
    }
}

https://user-images.githubusercontent.com/9727361/174053120-a2bc0e6b-9f06-4d46-b2b6-71091275ac9e.mov

b-onc commented 2 years ago

Hello @vadimue ,

This is documented behavior. Docs here: https://getstream.io/chat/docs/sdk/ios/uikit/controllers/channels/#2-create-a-controller

When you create a ChannelListController, like so:

 let controller = ChatClient.shared.channelListController(query: query)

you need to pass filter block to it. So the code becomes:

let query = ChannelListQuery(filter: .equal(.cid, to: try! ChannelId(cid: "messaging:Secret-Chat")))
let controller = ChatClient.shared.channelListController(query: query, filter: { $0.cid == ChannelId(type: .messaging, id: "Secret-Chat") })

The client needs to be able to differentiate between channels inserted to Database, so you need to duplicate the filtering logic.

Please let me know if you have further questions!

vadimue commented 2 years ago

Thanks a lot for a quick response @b-onc! It was really unobvious to me and my team. The issue is resolved.