From 90b2eae6e6b1b53d5f96f43ea3d1f54d5e9765d3 Mon Sep 17 00:00:00 2001 From: Toomas Vahter Date: Fri, 3 Oct 2025 09:40:05 +0300 Subject: [PATCH 1/3] Replace StreamCollection and LazyCachedMapCollection with Array --- DemoShare/DemoShareViewModel.swift | 2 +- .../ChannelController+SwiftUI.swift | 2 +- .../ChannelController/ChannelController.swift | 4 +- .../ChannelListController+SwiftUI.swift | 2 +- .../ChannelListController.swift | 2 +- ...ChannelWatcherListController+SwiftUI.swift | 2 +- .../ChatChannelWatcherListController.swift | 2 +- .../BackgroundListDatabaseObserver.swift | 4 +- .../MemberListController+SwiftUI.swift | 2 +- .../MemberListController.swift | 2 +- .../MessageController+SwiftUI.swift | 2 +- .../MessageController/MessageController.swift | 2 +- .../MessageReminderListController.swift | 2 +- .../PollController+SwiftUI.swift | 2 +- .../PollController/PollController.swift | 2 +- .../PollVoteListController+SwiftUI.swift | 2 +- .../PollVoteListController.swift | 2 +- .../ReactionListController+SwiftUI.swift | 2 +- .../ReactionListController.swift | 2 +- .../MessageSearchController+SwiftUI.swift | 2 +- .../MessageSearchController.swift | 2 +- .../ThreadListController+SwiftUI.swift | 2 +- .../ThreadListController.swift | 2 +- .../UserListController+SwiftUI.swift | 2 +- .../UserListController.swift | 2 +- .../ChannelListState+Observer.swift | 6 +- .../StateLayer/ChannelListState.swift | 2 +- .../StateLayer/ChatState+Observer.swift | 14 ++-- Sources/StreamChat/StateLayer/ChatState.swift | 6 +- .../StateLayerDatabaseObserver.swift | 12 +-- .../StateLayer/MemberListState+Observer.swift | 6 +- .../StateLayer/MemberListState.swift | 2 +- .../MessageSearchState+Observer.swift | 2 +- .../StateLayer/MessageSearchState.swift | 2 +- .../StateLayer/MessageState+Observer.swift | 10 +-- .../StreamChat/StateLayer/MessageState.swift | 4 +- .../ReactionListState+Observer.swift | 6 +- .../StateLayer/ReactionListState.swift | 2 +- .../StateLayer/UserListState+Observer.swift | 6 +- .../StreamChat/StateLayer/UserListState.swift | 2 +- .../StateLayer/UserSearchState.swift | 8 +- .../Utils/LazyCachedMapCollection.swift | 78 ------------------- .../StreamChat/Utils/StreamCollection.swift | 38 --------- .../Utils/UnreadMessageLookup.swift | 2 +- .../StreamChat/Workers/ChannelUpdater.swift | 6 +- .../ChatMessageListVC+DiffKit.swift | 2 +- .../ChatMessageList/ChatMessageListView.swift | 4 +- .../ChatThread/ChatThreadVC.swift | 2 +- StreamChat.xcodeproj/project.pbxproj | 16 ---- .../BackgroundListDatabaseObserver_Mock.swift | 4 +- .../ChannelListController_Mock.swift | 8 +- .../ChatChannelController_Mock.swift | 30 +++---- .../ChatChannelListController_Mock.swift | 6 +- ...hatChannelWatcherListController_Mock.swift | 4 +- .../ChatMessageController_Mock.swift | 12 +-- .../ChatMessageSearchController_Mock.swift | 10 +-- .../ChatThreadListController_Mock.swift | 8 +- .../Controllers/PollController_Mock.swift | 18 ++--- .../PollVoteListController_Mock.swift | 8 +- .../MemberListController_Mock.swift | 4 +- .../StreamChat/State/ChannelList_Mock.swift | 4 +- .../Mocks/StreamChat/State/Chat_Mock.swift | 4 +- .../StreamChat/State/MessageSearch_Mock.swift | 12 +-- .../StreamChat/State/UserSearch_Mock.swift | 2 +- .../Spy/ChatChannelController_Spy.swift | 8 +- ...PollVoteListController+SwiftUI_Tests.swift | 2 +- .../UserListController+SwiftUI_Tests.swift | 4 +- .../Utils/LazyCachedMapCollection_Tests.swift | 34 -------- .../Poll/PollResultsVoteListVC_Tests.swift | 4 +- 69 files changed, 156 insertions(+), 322 deletions(-) delete mode 100644 Sources/StreamChat/Utils/LazyCachedMapCollection.swift delete mode 100644 Sources/StreamChat/Utils/StreamCollection.swift delete mode 100644 Tests/StreamChatTests/Utils/LazyCachedMapCollection_Tests.swift diff --git a/DemoShare/DemoShareViewModel.swift b/DemoShare/DemoShareViewModel.swift index a6a45260fc9..2855f38da3f 100644 --- a/DemoShare/DemoShareViewModel.swift +++ b/DemoShare/DemoShareViewModel.swift @@ -32,7 +32,7 @@ class DemoShareViewModel: ObservableObject, ChatChannelControllerDelegate { chatClient.currentUserId } - @Published var channels = LazyCachedMapCollection() + @Published var channels: [ChatChannel] = [] @Published var text = "" @Published var images = [UIImage]() @Published var selectedChannel: ChatChannel? diff --git a/Sources/StreamChat/Controllers/ChannelController/ChannelController+SwiftUI.swift b/Sources/StreamChat/Controllers/ChannelController/ChannelController+SwiftUI.swift index 0599a5d1821..ee4d86c2a11 100644 --- a/Sources/StreamChat/Controllers/ChannelController/ChannelController+SwiftUI.swift +++ b/Sources/StreamChat/Controllers/ChannelController/ChannelController+SwiftUI.swift @@ -18,7 +18,7 @@ extension ChatChannelController { @Published public private(set) var channel: ChatChannel? /// The messages related to the channel. - @Published public private(set) var messages: LazyCachedMapCollection = [] + @Published public private(set) var messages: [ChatMessage] = [] /// The current state of the Controller. @Published public private(set) var state: DataController.State diff --git a/Sources/StreamChat/Controllers/ChannelController/ChannelController.swift b/Sources/StreamChat/Controllers/ChannelController/ChannelController.swift index 58935961cb4..fa5c779cea4 100644 --- a/Sources/StreamChat/Controllers/ChannelController/ChannelController.swift +++ b/Sources/StreamChat/Controllers/ChannelController/ChannelController.swift @@ -55,7 +55,7 @@ public class ChatChannelController: DataController, DelegateCallable, DataStoreP /// To observe changes of the messages, set your class as a delegate of this controller or use the provided /// `Combine` publishers. /// - public var messages: LazyCachedMapCollection { + public var messages: [ChatMessage] { if state == .initialized { setLocalStateBasedOnError(startDatabaseObservers()) } @@ -1697,7 +1697,7 @@ public class ChatChannelController: DataController, DelegateCallable, DataStoreP public func getFirstUnreadMessageId(for channel: ChatChannel) -> MessageId? { UnreadMessageLookup.firstUnreadMessageId( in: channel, - messages: StreamCollection(messages), + messages: messages, hasLoadedAllPreviousMessages: hasLoadedAllPreviousMessages, currentUserId: client.currentUserId ) diff --git a/Sources/StreamChat/Controllers/ChannelListController/ChannelListController+SwiftUI.swift b/Sources/StreamChat/Controllers/ChannelListController/ChannelListController+SwiftUI.swift index dcbdd5dbba7..2681913314a 100644 --- a/Sources/StreamChat/Controllers/ChannelListController/ChannelListController+SwiftUI.swift +++ b/Sources/StreamChat/Controllers/ChannelListController/ChannelListController+SwiftUI.swift @@ -15,7 +15,7 @@ extension ChatChannelListController { public let controller: ChatChannelListController /// The channels matching the query. - @Published public private(set) var channels: LazyCachedMapCollection = [] + @Published public private(set) var channels: [ChatChannel] = [] /// The current state of the Controller. @Published public private(set) var state: DataController.State diff --git a/Sources/StreamChat/Controllers/ChannelListController/ChannelListController.swift b/Sources/StreamChat/Controllers/ChannelListController/ChannelListController.swift index d181dd23710..3e46abea04b 100644 --- a/Sources/StreamChat/Controllers/ChannelListController/ChannelListController.swift +++ b/Sources/StreamChat/Controllers/ChannelListController/ChannelListController.swift @@ -45,7 +45,7 @@ public class ChatChannelListController: DataController, DelegateCallable, DataSt /// To observe changes of the channels, set your class as a delegate of this controller or use the provided /// `Combine` publishers. /// - public var channels: LazyCachedMapCollection { + public var channels: [ChatChannel] { startChannelListObserverIfNeeded() return channelListObserver.items } diff --git a/Sources/StreamChat/Controllers/ChannelWatcherListController/ChatChannelWatcherListController+SwiftUI.swift b/Sources/StreamChat/Controllers/ChannelWatcherListController/ChatChannelWatcherListController+SwiftUI.swift index dc6a9ffdbf5..3f976ff520d 100644 --- a/Sources/StreamChat/Controllers/ChannelWatcherListController/ChatChannelWatcherListController+SwiftUI.swift +++ b/Sources/StreamChat/Controllers/ChannelWatcherListController/ChatChannelWatcherListController+SwiftUI.swift @@ -16,7 +16,7 @@ extension ChatChannelWatcherListController { public let controller: ChatChannelWatcherListController /// The channel members. - @Published public private(set) var watchers: LazyCachedMapCollection = [] + @Published public private(set) var watchers: [ChatUser] = [] /// The current state of the controller. @Published public private(set) var state: DataController.State diff --git a/Sources/StreamChat/Controllers/ChannelWatcherListController/ChatChannelWatcherListController.swift b/Sources/StreamChat/Controllers/ChannelWatcherListController/ChatChannelWatcherListController.swift index 8e6a49f107d..edeff58cab0 100644 --- a/Sources/StreamChat/Controllers/ChannelWatcherListController/ChatChannelWatcherListController.swift +++ b/Sources/StreamChat/Controllers/ChannelWatcherListController/ChatChannelWatcherListController.swift @@ -27,7 +27,7 @@ public class ChatChannelWatcherListController: DataController, DelegateCallable, /// The channel watchers matching the query. /// To observe the watcher list changes, set your class as a delegate of this controller or use the provided /// `Combine` publishers. - public var watchers: LazyCachedMapCollection { + public var watchers: [ChatUser] { startObservingIfNeeded() return watchersObserver.items } diff --git a/Sources/StreamChat/Controllers/DatabaseObserver/BackgroundListDatabaseObserver.swift b/Sources/StreamChat/Controllers/DatabaseObserver/BackgroundListDatabaseObserver.swift index b57e34770f0..e692cfbb021 100644 --- a/Sources/StreamChat/Controllers/DatabaseObserver/BackgroundListDatabaseObserver.swift +++ b/Sources/StreamChat/Controllers/DatabaseObserver/BackgroundListDatabaseObserver.swift @@ -6,8 +6,8 @@ import CoreData import Foundation class BackgroundListDatabaseObserver: BackgroundDatabaseObserver, @unchecked Sendable { - var items: LazyCachedMapCollection { - LazyCachedMapCollection(elements: rawItems) + var items: [Item] { + rawItems } init( diff --git a/Sources/StreamChat/Controllers/MemberListController/MemberListController+SwiftUI.swift b/Sources/StreamChat/Controllers/MemberListController/MemberListController+SwiftUI.swift index 2c7fcfe26da..090d26608f0 100644 --- a/Sources/StreamChat/Controllers/MemberListController/MemberListController+SwiftUI.swift +++ b/Sources/StreamChat/Controllers/MemberListController/MemberListController+SwiftUI.swift @@ -16,7 +16,7 @@ extension ChatChannelMemberListController { public let controller: ChatChannelMemberListController /// The channel members. - @Published public private(set) var members: LazyCachedMapCollection = [] + @Published public private(set) var members: [ChatChannelMember] = [] /// The current state of the controller. @Published public private(set) var state: DataController.State diff --git a/Sources/StreamChat/Controllers/MemberListController/MemberListController.swift b/Sources/StreamChat/Controllers/MemberListController/MemberListController.swift index 2f13381be92..a598fd0a8fb 100644 --- a/Sources/StreamChat/Controllers/MemberListController/MemberListController.swift +++ b/Sources/StreamChat/Controllers/MemberListController/MemberListController.swift @@ -29,7 +29,7 @@ public class ChatChannelMemberListController: DataController, DelegateCallable, /// The channel members matching the query. /// To observe the member list changes, set your class as a delegate of this controller or use the provided /// `Combine` publishers. - public var members: LazyCachedMapCollection { + public var members: [ChatChannelMember] { startObservingIfNeeded() return memberListObserver.items } diff --git a/Sources/StreamChat/Controllers/MessageController/MessageController+SwiftUI.swift b/Sources/StreamChat/Controllers/MessageController/MessageController+SwiftUI.swift index ac5491a84d1..5851c42795d 100644 --- a/Sources/StreamChat/Controllers/MessageController/MessageController+SwiftUI.swift +++ b/Sources/StreamChat/Controllers/MessageController/MessageController+SwiftUI.swift @@ -18,7 +18,7 @@ extension ChatMessageController { @Published public private(set) var message: ChatMessage? /// The replies the message controller observes. - @Published public private(set) var replies: LazyCachedMapCollection = [] + @Published public private(set) var replies: [ChatMessage] = [] /// The reactions the message controller observes. @Published public private(set) var reactions: [ChatMessageReaction] = [] diff --git a/Sources/StreamChat/Controllers/MessageController/MessageController.swift b/Sources/StreamChat/Controllers/MessageController/MessageController.swift index adac7b620d5..446408e4a24 100644 --- a/Sources/StreamChat/Controllers/MessageController/MessageController.swift +++ b/Sources/StreamChat/Controllers/MessageController/MessageController.swift @@ -47,7 +47,7 @@ public class ChatMessageController: DataController, DelegateCallable, DataStoreP /// To observe changes of the replies, set your class as a delegate of this controller or use the provided /// `Combine` publishers. /// - public var replies: LazyCachedMapCollection { + public var replies: [ChatMessage] { startObserversIfNeeded() return repliesObserver?.items ?? [] } diff --git a/Sources/StreamChat/Controllers/MessageReminderListController/MessageReminderListController.swift b/Sources/StreamChat/Controllers/MessageReminderListController/MessageReminderListController.swift index 65f92ab2abe..e8d63614ce5 100644 --- a/Sources/StreamChat/Controllers/MessageReminderListController/MessageReminderListController.swift +++ b/Sources/StreamChat/Controllers/MessageReminderListController/MessageReminderListController.swift @@ -40,7 +40,7 @@ public class MessageReminderListController: DataController, DelegateCallable, Da /// /// To observe changes of the reminders, set your class as a delegate of this controller or use the provided /// `Combine` publishers. - public var reminders: LazyCachedMapCollection { + public var reminders: [MessageReminder] { startMessageRemindersObserverIfNeeded() return messageRemindersObserver.items } diff --git a/Sources/StreamChat/Controllers/PollController/PollController+SwiftUI.swift b/Sources/StreamChat/Controllers/PollController/PollController+SwiftUI.swift index 5669698de23..c6160704f83 100644 --- a/Sources/StreamChat/Controllers/PollController/PollController+SwiftUI.swift +++ b/Sources/StreamChat/Controllers/PollController/PollController+SwiftUI.swift @@ -18,7 +18,7 @@ extension PollController { @Published public private(set) var poll: Poll? /// The current user's votes. - @Published public private(set) var ownVotes: LazyCachedMapCollection = [] + @Published public private(set) var ownVotes: [PollVote] = [] /// The current state of the controller. @Published public private(set) var state: DataController.State diff --git a/Sources/StreamChat/Controllers/PollController/PollController.swift b/Sources/StreamChat/Controllers/PollController/PollController.swift index 52dc931fc42..0bb014d236a 100644 --- a/Sources/StreamChat/Controllers/PollController/PollController.swift +++ b/Sources/StreamChat/Controllers/PollController/PollController.swift @@ -35,7 +35,7 @@ public class PollController: DataController, DelegateCallable, DataStoreProvider } /// Returns the current user's votes. - public var ownVotes: LazyCachedMapCollection { + public var ownVotes: [PollVote] { ownVotesObserver.items } diff --git a/Sources/StreamChat/Controllers/PollController/PollVoteListController+SwiftUI.swift b/Sources/StreamChat/Controllers/PollController/PollVoteListController+SwiftUI.swift index 40b09c3ddca..0f4f8df5c12 100644 --- a/Sources/StreamChat/Controllers/PollController/PollVoteListController+SwiftUI.swift +++ b/Sources/StreamChat/Controllers/PollController/PollVoteListController+SwiftUI.swift @@ -16,7 +16,7 @@ extension PollVoteListController { public let controller: PollVoteListController /// The poll votes. - @Published public private(set) var votes: LazyCachedMapCollection = [] + @Published public private(set) var votes: [PollVote] = [] /// The current state of the controller. @Published public private(set) var state: DataController.State diff --git a/Sources/StreamChat/Controllers/PollController/PollVoteListController.swift b/Sources/StreamChat/Controllers/PollController/PollVoteListController.swift index 4ade6f2c7f2..657f0a1f99e 100644 --- a/Sources/StreamChat/Controllers/PollController/PollVoteListController.swift +++ b/Sources/StreamChat/Controllers/PollController/PollVoteListController.swift @@ -41,7 +41,7 @@ public class PollVoteListController: DataController, DelegateCallable, DataStore /// /// To observe changes of the votes, set your class as a delegate of this controller or use the provided /// `Combine` publishers. - public var votes: LazyCachedMapCollection { + public var votes: [PollVote] { startPollVotesListObserverIfNeeded() return pollVotesObserver.items } diff --git a/Sources/StreamChat/Controllers/ReactionListController/ReactionListController+SwiftUI.swift b/Sources/StreamChat/Controllers/ReactionListController/ReactionListController+SwiftUI.swift index 61da08e3ef1..0e9a5b0c861 100644 --- a/Sources/StreamChat/Controllers/ReactionListController/ReactionListController+SwiftUI.swift +++ b/Sources/StreamChat/Controllers/ReactionListController/ReactionListController+SwiftUI.swift @@ -16,7 +16,7 @@ extension ChatReactionListController { public let controller: ChatReactionListController /// The message reactions. - @Published public private(set) var reactions: LazyCachedMapCollection = [] + @Published public private(set) var reactions: [ChatMessageReaction] = [] /// The current state of the controller. @Published public private(set) var state: DataController.State diff --git a/Sources/StreamChat/Controllers/ReactionListController/ReactionListController.swift b/Sources/StreamChat/Controllers/ReactionListController/ReactionListController.swift index a0a1c01bc1d..6a8d05e778d 100644 --- a/Sources/StreamChat/Controllers/ReactionListController/ReactionListController.swift +++ b/Sources/StreamChat/Controllers/ReactionListController/ReactionListController.swift @@ -32,7 +32,7 @@ public class ChatReactionListController: DataController, DelegateCallable, DataS /// /// To observe changes of the reactions, set your class as a delegate of this controller or use the provided /// `Combine` publishers. - public var reactions: LazyCachedMapCollection { + public var reactions: [ChatMessageReaction] { startReactionListObserverIfNeeded() return reactionListObserver.items } diff --git a/Sources/StreamChat/Controllers/SearchControllers/MessageSearchController/MessageSearchController+SwiftUI.swift b/Sources/StreamChat/Controllers/SearchControllers/MessageSearchController/MessageSearchController+SwiftUI.swift index 6540ab9f3dd..9c86f20d934 100644 --- a/Sources/StreamChat/Controllers/SearchControllers/MessageSearchController/MessageSearchController+SwiftUI.swift +++ b/Sources/StreamChat/Controllers/SearchControllers/MessageSearchController/MessageSearchController+SwiftUI.swift @@ -15,7 +15,7 @@ extension ChatMessageSearchController { public let controller: ChatMessageSearchController /// The current result of messages. - @Published public private(set) var messages: LazyCachedMapCollection = [] + @Published public private(set) var messages: [ChatMessage] = [] /// The current state of the controller. @Published public private(set) var state: DataController.State diff --git a/Sources/StreamChat/Controllers/SearchControllers/MessageSearchController/MessageSearchController.swift b/Sources/StreamChat/Controllers/SearchControllers/MessageSearchController/MessageSearchController.swift index 71158b4cb32..adb3c237d60 100644 --- a/Sources/StreamChat/Controllers/SearchControllers/MessageSearchController/MessageSearchController.swift +++ b/Sources/StreamChat/Controllers/SearchControllers/MessageSearchController/MessageSearchController.swift @@ -61,7 +61,7 @@ public class ChatMessageSearchController: DataController, DelegateCallable, Data /// /// To observe changes of the messages, set your class as a delegate of this controller or use the provided /// `Combine` publishers. - public var messages: LazyCachedMapCollection { + public var messages: [ChatMessage] { startObserversIfNeeded() return messagesObserver?.items ?? [] } diff --git a/Sources/StreamChat/Controllers/ThreadListController/ThreadListController+SwiftUI.swift b/Sources/StreamChat/Controllers/ThreadListController/ThreadListController+SwiftUI.swift index aaa8a0af3ea..2b8ab8080a0 100644 --- a/Sources/StreamChat/Controllers/ThreadListController/ThreadListController+SwiftUI.swift +++ b/Sources/StreamChat/Controllers/ThreadListController/ThreadListController+SwiftUI.swift @@ -15,7 +15,7 @@ extension ChatThreadListController { internal let controller: ChatThreadListController /// The threads. - @Published internal private(set) var threads: LazyCachedMapCollection = [] + @Published internal private(set) var threads: [ChatThread] = [] /// The current state of the controller. @Published internal private(set) var state: DataController.State diff --git a/Sources/StreamChat/Controllers/ThreadListController/ThreadListController.swift b/Sources/StreamChat/Controllers/ThreadListController/ThreadListController.swift index fb3a68f43e2..62225d8f522 100644 --- a/Sources/StreamChat/Controllers/ThreadListController/ThreadListController.swift +++ b/Sources/StreamChat/Controllers/ThreadListController/ThreadListController.swift @@ -34,7 +34,7 @@ public class ChatThreadListController: DataController, DelegateCallable, DataSto /// /// To observe changes of the threads, set your class as a delegate of this controller /// or use the provided combine publishers. - public var threads: LazyCachedMapCollection { + public var threads: [ChatThread] { startThreadListObserverIfNeeded() return threadListObserver.items } diff --git a/Sources/StreamChat/Controllers/UserListController/UserListController+SwiftUI.swift b/Sources/StreamChat/Controllers/UserListController/UserListController+SwiftUI.swift index 70f16546b79..1481798c791 100644 --- a/Sources/StreamChat/Controllers/UserListController/UserListController+SwiftUI.swift +++ b/Sources/StreamChat/Controllers/UserListController/UserListController+SwiftUI.swift @@ -15,7 +15,7 @@ extension ChatUserListController { public let controller: ChatUserListController /// The users matching the query. - @Published public private(set) var users: LazyCachedMapCollection = [] + @Published public private(set) var users: [ChatUser] = [] /// The current state of the Controller. @Published public private(set) var state: DataController.State diff --git a/Sources/StreamChat/Controllers/UserListController/UserListController.swift b/Sources/StreamChat/Controllers/UserListController/UserListController.swift index 861c3a9a1c9..5c398946522 100644 --- a/Sources/StreamChat/Controllers/UserListController/UserListController.swift +++ b/Sources/StreamChat/Controllers/UserListController/UserListController.swift @@ -32,7 +32,7 @@ public class ChatUserListController: DataController, DelegateCallable, DataStore /// To observe changes of the users, set your class as a delegate of this controller or use the provided /// `Combine` publishers. /// - public var users: LazyCachedMapCollection { + public var users: [ChatUser] { startUserListObserverIfNeeded() return userListObserver.items } diff --git a/Sources/StreamChat/StateLayer/ChannelListState+Observer.swift b/Sources/StreamChat/StateLayer/ChannelListState+Observer.swift index 35709e5fc38..e0849a68ba4 100644 --- a/Sources/StreamChat/StateLayer/ChannelListState+Observer.swift +++ b/Sources/StreamChat/StateLayer/ChannelListState+Observer.swift @@ -50,16 +50,16 @@ extension ChannelListState { } struct Handlers { - let channelsDidChange: @Sendable @MainActor (StreamCollection) async -> Void + let channelsDidChange: @Sendable @MainActor ([ChatChannel]) async -> Void } - func start(with handlers: Handlers) -> StreamCollection { + func start(with handlers: Handlers) -> [ChatChannel] { do { channelListLinker.start(with: eventNotificationCenter) return try channelListObserver.startObserving(didChange: handlers.channelsDidChange) } catch { log.error("Failed to start the channel list observer for query: \(query)") - return StreamCollection([]) + return [] } } } diff --git a/Sources/StreamChat/StateLayer/ChannelListState.swift b/Sources/StreamChat/StateLayer/ChannelListState.swift index e4b7ada4343..6dd10817822 100644 --- a/Sources/StreamChat/StateLayer/ChannelListState.swift +++ b/Sources/StreamChat/StateLayer/ChannelListState.swift @@ -34,5 +34,5 @@ import Foundation public let query: ChannelListQuery /// An array of channels for the specified ``ChannelListQuery``. - @Published public internal(set) var channels = StreamCollection([]) + @Published public internal(set) var channels: [ChatChannel] = [] } diff --git a/Sources/StreamChat/StateLayer/ChatState+Observer.swift b/Sources/StreamChat/StateLayer/ChatState+Observer.swift index 87c39347bf1..bf4287fac74 100644 --- a/Sources/StreamChat/StateLayer/ChatState+Observer.swift +++ b/Sources/StreamChat/StateLayer/ChatState+Observer.swift @@ -55,18 +55,18 @@ extension ChatState { struct Handlers { let channelDidChange: @Sendable @MainActor (ChatChannel?) async -> Void - let membersDidChange: @Sendable @MainActor (StreamCollection) async -> Void - let messagesDidChange: @Sendable @MainActor (StreamCollection) async -> Void - let watchersDidChange: @Sendable @MainActor (StreamCollection) async -> Void + let membersDidChange: @Sendable @MainActor ([ChatChannelMember]) async -> Void + let messagesDidChange: @Sendable @MainActor ([ChatMessage]) async -> Void + let watchersDidChange: @Sendable @MainActor ([ChatUser]) async -> Void } @MainActor func start( with handlers: Handlers ) -> ( channel: ChatChannel?, - members: StreamCollection, - messages: StreamCollection, - watchers: StreamCollection + members: [ChatChannelMember], + messages: [ChatMessage], + watchers: [ChatUser] ) { memberListObserver = memberListState.$members .dropFirst() @@ -81,7 +81,7 @@ extension ChatState { return (channel, memberListState.members, messages, watchers) } catch { log.error("Failed to start the observers for cid: \(cid) with error \(error)") - return (nil, StreamCollection([]), StreamCollection([]), StreamCollection([])) + return (nil, [], [], []) } } } diff --git a/Sources/StreamChat/StateLayer/ChatState.swift b/Sources/StreamChat/StateLayer/ChatState.swift index 3288e1b115a..3eda6c97157 100644 --- a/Sources/StreamChat/StateLayer/ChatState.swift +++ b/Sources/StreamChat/StateLayer/ChatState.swift @@ -59,7 +59,7 @@ import Foundation /// An array of loaded channel members. /// /// Use load members in ``Chat`` for loading more members. - @Published public private(set) var members = StreamCollection([]) + @Published public private(set) var members: [ChatChannelMember] = [] /// The sorting order for channel members (the default sorting is by created at in ascending order). public let memberSorting: [Sorting] @@ -74,7 +74,7 @@ import Foundation /// Messages are ordered by timestamp and ``messageOrder`` (In case of ``MessageOrdering/bottomToTop`` the list is sorted in ascending order). /// /// Use load messages in ``Chat`` for loading more messages. - @Published public internal(set) var messages = StreamCollection([]) + @Published public internal(set) var messages: [ChatMessage] = [] /// A Boolean value that returns whether the oldest messages have all been loaded or not. public var hasLoadedAllOldestMessages: Bool { @@ -161,7 +161,7 @@ import Foundation /// An array of users who are currently watching the channel. /// /// Use load watchers method in ``Chat`` for populating this array. - @Published public internal(set) var watchers = StreamCollection([]) + @Published public internal(set) var watchers: [ChatUser] = [] } // MARK: - Internal diff --git a/Sources/StreamChat/StateLayer/DatabaseObserver/StateLayerDatabaseObserver.swift b/Sources/StreamChat/StateLayer/DatabaseObserver/StateLayerDatabaseObserver.swift index 0a2d7463766..f8bd590b171 100644 --- a/Sources/StreamChat/StateLayer/DatabaseObserver/StateLayerDatabaseObserver.swift +++ b/Sources/StreamChat/StateLayer/DatabaseObserver/StateLayerDatabaseObserver.swift @@ -153,12 +153,12 @@ extension StateLayerDatabaseObserver where ResultType == ListResult { ) } - var items: StreamCollection { - var collection: StreamCollection! + var items: [Item] { + var collection: [Item]! context.performAndWait { // When we already have loaded items, reuse them, otherwise refetch all let items = reuseItems ?? updateItems(nil) - collection = StreamCollection(items) + collection = items } return collection } @@ -168,7 +168,7 @@ extension StateLayerDatabaseObserver where ResultType == ListResult { /// - Parameter didChange: The callback which is triggered when the observed item changes. Runs on the ``MainActor``. /// /// - Returns: Returns the current state of items in the local database. - func startObserving(didChange: @escaping @Sendable @MainActor (StreamCollection) async -> Void) throws -> StreamCollection where Item: Sendable { + func startObserving(didChange: @escaping @Sendable @MainActor ([Item]) async -> Void) throws -> [Item] where Item: Sendable { try startObserving(onContextDidChange: { items, _ in Task.mainActor { await didChange(items) } }) @@ -181,12 +181,12 @@ extension StateLayerDatabaseObserver where ResultType == ListResult { /// - Note: Use it if you need to do additional processing on the context's queue. /// /// - Returns: Returns the current state of items in the local database. - @discardableResult func startObserving(onContextDidChange: @escaping (StreamCollection, [ListChange]) -> Void) throws -> StreamCollection { + @discardableResult func startObserving(onContextDidChange: @escaping ([Item], [ListChange]) -> Void) throws -> [Item] { changeAggregator.onDidChange = { [weak self] changes in guard let self else { return } // Runs on the NSManagedObjectContext's queue, therefore skip performAndWait let items = self.updateItems(changes) - onContextDidChange(StreamCollection(items), changes) + onContextDidChange(items, changes) } frc.delegate = changeAggregator try frc.performFetch() diff --git a/Sources/StreamChat/StateLayer/MemberListState+Observer.swift b/Sources/StreamChat/StateLayer/MemberListState+Observer.swift index 5a113943f87..a42ef4c0c7e 100644 --- a/Sources/StreamChat/StateLayer/MemberListState+Observer.swift +++ b/Sources/StreamChat/StateLayer/MemberListState+Observer.swift @@ -18,15 +18,15 @@ extension MemberListState { } struct Handlers { - let membersDidChange: @Sendable @MainActor (StreamCollection) async -> Void + let membersDidChange: @Sendable @MainActor ([ChatChannelMember]) async -> Void } - func start(with handlers: Handlers) -> StreamCollection { + func start(with handlers: Handlers) -> [ChatChannelMember] { do { return try memberListObserver.startObserving(didChange: handlers.membersDidChange) } catch { log.error("Failed to start the member list observer with error \(error)") - return StreamCollection([]) + return [] } } } diff --git a/Sources/StreamChat/StateLayer/MemberListState.swift b/Sources/StreamChat/StateLayer/MemberListState.swift index 2407370a79f..cdebf524a89 100644 --- a/Sources/StreamChat/StateLayer/MemberListState.swift +++ b/Sources/StreamChat/StateLayer/MemberListState.swift @@ -20,5 +20,5 @@ import Foundation public let query: ChannelMemberListQuery /// An array of members for the specified ``ChannelMemberListQuery``. - @Published public private(set) var members = StreamCollection([]) + @Published public private(set) var members: [ChatChannelMember] = [] } diff --git a/Sources/StreamChat/StateLayer/MessageSearchState+Observer.swift b/Sources/StreamChat/StateLayer/MessageSearchState+Observer.swift index 2502c4c4215..fd2a9e980e4 100644 --- a/Sources/StreamChat/StateLayer/MessageSearchState+Observer.swift +++ b/Sources/StreamChat/StateLayer/MessageSearchState+Observer.swift @@ -19,7 +19,7 @@ extension MessageSearchState { } struct Handlers { - let messagesDidChange: @Sendable @MainActor (StreamCollection) async -> Void + let messagesDidChange: @Sendable @MainActor ([ChatMessage]) async -> Void } private var handlers: Handlers? diff --git a/Sources/StreamChat/StateLayer/MessageSearchState.swift b/Sources/StreamChat/StateLayer/MessageSearchState.swift index 6e3d13e41d6..996fd69cca2 100644 --- a/Sources/StreamChat/StateLayer/MessageSearchState.swift +++ b/Sources/StreamChat/StateLayer/MessageSearchState.swift @@ -25,7 +25,7 @@ import Foundation @Published public private(set) var query: MessageSearchQuery? /// An array of search results for the specified query and pagination state. - @Published public internal(set) var messages = StreamCollection([]) + @Published public internal(set) var messages: [ChatMessage] = [] // MARK: - Mutating the State diff --git a/Sources/StreamChat/StateLayer/MessageState+Observer.swift b/Sources/StreamChat/StateLayer/MessageState+Observer.swift index e6ba0db9705..5d69c09858b 100644 --- a/Sources/StreamChat/StateLayer/MessageState+Observer.swift +++ b/Sources/StreamChat/StateLayer/MessageState+Observer.swift @@ -48,16 +48,16 @@ extension MessageState { struct Handlers { let messageDidChange: @Sendable @MainActor (ChatMessage) async -> Void - let reactionsDidChange: @Sendable @MainActor (StreamCollection) async -> Void - let repliesDidChange: @Sendable @MainActor (StreamCollection) async -> Void + let reactionsDidChange: @Sendable @MainActor ([ChatMessageReaction]) async -> Void + let repliesDidChange: @Sendable @MainActor ([ChatMessage]) async -> Void } func start( with handlers: Handlers ) -> ( message: ChatMessage?, - reactions: StreamCollection, - replies: StreamCollection + reactions: [ChatMessageReaction], + replies: [ChatMessage] ) { do { let message = try messageObserver.startObserving(onContextDidChange: { message, _ in @@ -69,7 +69,7 @@ extension MessageState { return (message, reactions, replies) } catch { log.error("Failed to start the observers for message: \(messageId) with error \(error)") - return (nil, StreamCollection([]), StreamCollection([])) + return (nil, [], []) } } } diff --git a/Sources/StreamChat/StateLayer/MessageState.swift b/Sources/StreamChat/StateLayer/MessageState.swift index 6deb1107062..cd9ba7b75c0 100644 --- a/Sources/StreamChat/StateLayer/MessageState.swift +++ b/Sources/StreamChat/StateLayer/MessageState.swift @@ -55,12 +55,12 @@ import Foundation /// An array of loaded message reactions sorted by ``ChatMessageReaction/updatedAt`` with descending order. /// /// Use ``Chat/loadReactions(of:pagination:)`` for loading more reactions. - @Published public private(set) var reactions = StreamCollection([]) + @Published public private(set) var reactions: [ChatMessageReaction] = [] // MARK: - Replies /// An array of loaded replies sorted by ``MessageOrdering``. - @Published public internal(set) var replies = StreamCollection([]) + @Published public internal(set) var replies: [ChatMessage] = [] /// A Boolean value that returns whether the oldest replies have all been loaded or not. public var hasLoadedAllOldestReplies: Bool { diff --git a/Sources/StreamChat/StateLayer/ReactionListState+Observer.swift b/Sources/StreamChat/StateLayer/ReactionListState+Observer.swift index 73d55fb5a5e..c9f120953c7 100644 --- a/Sources/StreamChat/StateLayer/ReactionListState+Observer.swift +++ b/Sources/StreamChat/StateLayer/ReactionListState+Observer.swift @@ -18,15 +18,15 @@ extension ReactionListState { } struct Handlers { - let reactionsDidChange: @Sendable @MainActor (StreamCollection) async -> Void + let reactionsDidChange: @Sendable @MainActor ([ChatMessageReaction]) async -> Void } - func start(with handlers: Handlers) -> StreamCollection { + func start(with handlers: Handlers) -> [ChatMessageReaction] { do { return try reactionListObserver.startObserving(didChange: handlers.reactionsDidChange) } catch { log.error("Failed to start the reaction list observer with error \(error)") - return StreamCollection([]) + return [] } } } diff --git a/Sources/StreamChat/StateLayer/ReactionListState.swift b/Sources/StreamChat/StateLayer/ReactionListState.swift index 15d5cf5c82b..ce157fd05e1 100644 --- a/Sources/StreamChat/StateLayer/ReactionListState.swift +++ b/Sources/StreamChat/StateLayer/ReactionListState.swift @@ -20,5 +20,5 @@ import Foundation public let query: ReactionListQuery /// An array of reactions for the specified ``ReactionListQuery``. - @Published public private(set) var reactions = StreamCollection([]) + @Published public private(set) var reactions: [ChatMessageReaction] = [] } diff --git a/Sources/StreamChat/StateLayer/UserListState+Observer.swift b/Sources/StreamChat/StateLayer/UserListState+Observer.swift index feba04069da..9f299339a47 100644 --- a/Sources/StreamChat/StateLayer/UserListState+Observer.swift +++ b/Sources/StreamChat/StateLayer/UserListState+Observer.swift @@ -20,15 +20,15 @@ extension UserListState { } struct Handlers { - let usersDidChange: @Sendable @MainActor (StreamCollection) async -> Void + let usersDidChange: @Sendable @MainActor ([ChatUser]) async -> Void } - func start(with handlers: Handlers) -> StreamCollection { + func start(with handlers: Handlers) -> [ChatUser] { do { return try usersObserver.startObserving(didChange: handlers.usersDidChange) } catch { log.error("Failed to start the user list observer for query: \(query)") - return StreamCollection([]) + return [] } } } diff --git a/Sources/StreamChat/StateLayer/UserListState.swift b/Sources/StreamChat/StateLayer/UserListState.swift index 03c04ffb41c..bcd829d98aa 100644 --- a/Sources/StreamChat/StateLayer/UserListState.swift +++ b/Sources/StreamChat/StateLayer/UserListState.swift @@ -21,5 +21,5 @@ import Foundation public let query: UserListQuery /// An array of users for the specified ``UserListQuery``. - @Published public private(set) var users = StreamCollection([]) + @Published public private(set) var users: [ChatUser] = [] } diff --git a/Sources/StreamChat/StateLayer/UserSearchState.swift b/Sources/StreamChat/StateLayer/UserSearchState.swift index 48f9d727cd5..786890f38e7 100644 --- a/Sources/StreamChat/StateLayer/UserSearchState.swift +++ b/Sources/StreamChat/StateLayer/UserSearchState.swift @@ -12,7 +12,7 @@ import Foundation @Published public internal(set) var query: UserListQuery? /// An array of search results for the specified query and pagination state. - @Published public internal(set) var users = StreamCollection([]) + @Published public internal(set) var users: [ChatUser] = [] } extension UserSearchState { @@ -36,16 +36,16 @@ extension UserSearchState { // Discard since filter or sorting has changed return } - let result: StreamCollection + let result: [ChatUser] if completedQuery.pagination?.offset == 0 { // Reset to the first page - result = StreamCollection(incomingUsers) + result = incomingUsers } else { // Filter and sorting are the same but incoming users might contain duplicates (depends how pagination is used) let incomingIds = Set(incomingUsers.map(\.id)) let incomingRemovedUsers = users.filter { !incomingIds.contains($0.id) } let sortValues = completedQuery.sort.map(\.sortValue) - result = StreamCollection((incomingRemovedUsers + incomingUsers).sorted(using: sortValues)) + result = (incomingRemovedUsers + incomingUsers).sorted(using: sortValues) } users = result } diff --git a/Sources/StreamChat/Utils/LazyCachedMapCollection.swift b/Sources/StreamChat/Utils/LazyCachedMapCollection.swift deleted file mode 100644 index 927f0c6f66f..00000000000 --- a/Sources/StreamChat/Utils/LazyCachedMapCollection.swift +++ /dev/null @@ -1,78 +0,0 @@ -// -// Copyright © 2025 Stream.io Inc. All rights reserved. -// - -import CoreData -import Foundation - -/// An ordered, random-access collection. -/// -/// - Important: `LazyCachedMapCollection` used to be a lazy collection applying transformations on the first element access. Since SDK version 4.60.0 it is not lazy anymore and works the same way as the Swift's Array type. -public struct LazyCachedMapCollection: RandomAccessCollection { - public typealias Index = Int - - public func index(before i: Index) -> Index { - mappedElements.index(before: i) - } - - public func index(after i: Index) -> Index { - mappedElements.index(after: i) - } - - public var startIndex: Index { mappedElements.startIndex } - - public var endIndex: Index { mappedElements.endIndex } - - public var count: Index { mappedElements.count } - - public init(_ collection: LazyCachedMapCollection) { - mappedElements = collection.mappedElements - } - - private var mappedElements: [Element] - - init(elements: [Element]) { - mappedElements = elements - } - - public init( - source: Collection, - map: @escaping (SourceElement) -> Element, - context: NSManagedObjectContext? = nil - ) where Collection.Element == SourceElement, Collection.Index == Index { - mappedElements = source.map(map) - } - - public subscript(position: Index) -> Element { - mappedElements[position] - } - - public mutating func append(_ element: Element) { - mappedElements.append(element) - } -} - -extension LazyCachedMapCollection: ExpressibleByArrayLiteral { - public typealias ArrayLiteralElement = Element - - public init(arrayLiteral elements: Element...) { - mappedElements = elements - } -} - -extension LazyCachedMapCollection: Equatable where Element: Equatable { - public static func == (lhs: LazyCachedMapCollection, rhs: LazyCachedMapCollection) -> Bool { - guard lhs.count == rhs.count else { return false } - return zip(lhs, rhs).allSatisfy(==) - } -} - -extension RandomAccessCollection where Index == Int { - /// Lazily apply transformation to sequence - public func lazyCachedMap( - _ transformation: @escaping (Element) -> T, - context: NSManagedObjectContext? = nil - ) -> LazyCachedMapCollection { - .init(source: self, map: transformation, context: context) - } -} diff --git a/Sources/StreamChat/Utils/StreamCollection.swift b/Sources/StreamChat/Utils/StreamCollection.swift deleted file mode 100644 index 23f46da2ae8..00000000000 --- a/Sources/StreamChat/Utils/StreamCollection.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright © 2025 Stream.io Inc. All rights reserved. -// - -import Foundation - -/// A collection wrapping the base collection which allows base collections of different types. -/// -/// - Note: The type of the base collection can change in the future. -public struct StreamCollection: RandomAccessCollection { - public typealias Index = Int - private let baseCollection: [Element] - - /// Creates an instance of the collection using the base collection as the data source. - public init(_ baseCollection: BaseCollection) where BaseCollection: RandomAccessCollection, BaseCollection.Element == Element, BaseCollection.Index == Index { - self.baseCollection = Array(baseCollection) - } - - /// The position of the first element in a non-empty collection. - public var startIndex: Index { baseCollection.startIndex } - - /// The collection's “past the end” position—that is, the position one greater than the last valid subscript argument. - public var endIndex: Index { baseCollection.endIndex } - - /// Accesses the element at the specified position. - public subscript(position: Index) -> Element { - baseCollection[position] - } -} - -extension StreamCollection: Sendable where Element: Sendable {} - -extension StreamCollection: CustomStringConvertible { - public var description: String { - let contents = map { String(describing: $0) }.joined(separator: ", ") - return "\(Self.self)(\(contents))" - } -} diff --git a/Sources/StreamChat/Utils/UnreadMessageLookup.swift b/Sources/StreamChat/Utils/UnreadMessageLookup.swift index e5b232ad161..72fa6fee261 100644 --- a/Sources/StreamChat/Utils/UnreadMessageLookup.swift +++ b/Sources/StreamChat/Utils/UnreadMessageLookup.swift @@ -7,7 +7,7 @@ import Foundation enum UnreadMessageLookup { static func firstUnreadMessageId( in channel: ChatChannel, - messages: StreamCollection, + messages: [ChatMessage], hasLoadedAllPreviousMessages: Bool, currentUserId: UserId? ) -> MessageId? { diff --git a/Sources/StreamChat/Workers/ChannelUpdater.swift b/Sources/StreamChat/Workers/ChannelUpdater.swift index fc61a60cd0b..5eaefeac793 100644 --- a/Sources/StreamChat/Workers/ChannelUpdater.swift +++ b/Sources/StreamChat/Workers/ChannelUpdater.swift @@ -1144,7 +1144,7 @@ extension ChannelUpdater { before messageId: MessageId?, limit: Int?, channelQuery: ChannelQuery, - loaded: StreamCollection + loaded: [ChatMessage] ) async throws { guard !paginationState.isLoadingPreviousMessages else { return } guard !paginationState.hasLoadedAllPreviousMessages else { return } @@ -1161,7 +1161,7 @@ extension ChannelUpdater { after messageId: MessageId?, limit: Int?, channelQuery: ChannelQuery, - loaded: StreamCollection + loaded: [ChatMessage] ) async throws { guard !paginationState.isLoadingNextMessages else { return } guard !paginationState.hasLoadedAllNextMessages else { return } @@ -1177,7 +1177,7 @@ extension ChannelUpdater { around messageId: MessageId, limit: Int?, channelQuery: ChannelQuery, - loaded: StreamCollection + loaded: [ChatMessage] ) async throws { guard !paginationState.isLoadingMiddleMessages else { return } let limit = limit ?? channelQuery.pagination?.pageSize ?? .messagesPageSize diff --git a/Sources/StreamChatUI/ChatMessageList/ChatMessageListVC+DiffKit.swift b/Sources/StreamChatUI/ChatMessageList/ChatMessageListVC+DiffKit.swift index 65ee6ab34e7..5b755046d37 100644 --- a/Sources/StreamChatUI/ChatMessageList/ChatMessageListVC+DiffKit.swift +++ b/Sources/StreamChatUI/ChatMessageList/ChatMessageListVC+DiffKit.swift @@ -12,7 +12,7 @@ public extension ChatMessageListVC { } /// Set the new message snapshot reported by the data controller. - func setNewMessagesSnapshot(_ messages: LazyCachedMapCollection) { + func setNewMessagesSnapshot(_ messages: [ChatMessage]) { listView.currentMessagesFromDataSource = messages listView.newMessagesSnapshot = messages } diff --git a/Sources/StreamChatUI/ChatMessageList/ChatMessageListView.swift b/Sources/StreamChatUI/ChatMessageList/ChatMessageListView.swift index 41404c5039b..6164d33d759 100644 --- a/Sources/StreamChatUI/ChatMessageList/ChatMessageListView.swift +++ b/Sources/StreamChatUI/ChatMessageList/ChatMessageListView.swift @@ -23,7 +23,7 @@ open class ChatMessageListView: UITableView, Customizable, ComponentsProvider { /// This property is especially useful when resetting the skipped messages /// since we want to reload the data and insert back the skipped messages, for this, /// we update the messages data with the one originally reported by the data controller. - internal var currentMessagesFromDataSource: LazyCachedMapCollection = [] + internal var currentMessagesFromDataSource: [ChatMessage] = [] /// The current messages from the data source, including skipped messages as an array. /// Used mostly for the Livestream version of the message list. @@ -31,7 +31,7 @@ open class ChatMessageListView: UITableView, Customizable, ComponentsProvider { /// The new messages snapshot reported by the channel or message controller. /// If messages are being skipped, this snapshot doesn't include skipped messages. - internal var newMessagesSnapshot: LazyCachedMapCollection = [] + internal var newMessagesSnapshot: [ChatMessage] = [] /// The new messages snapshot reported by the channel or message controller as an array. /// Used mostly for the Livestream version of the message list. diff --git a/Sources/StreamChatUI/ChatThread/ChatThreadVC.swift b/Sources/StreamChatUI/ChatThread/ChatThreadVC.swift index 69af436fb14..9bef8ba7744 100644 --- a/Sources/StreamChatUI/ChatThread/ChatThreadVC.swift +++ b/Sources/StreamChatUI/ChatThread/ChatThreadVC.swift @@ -507,7 +507,7 @@ open class ChatThreadVC: _ViewController, } /// Gets the replies of the thread, plus the parent message if needed. - private func getMessages(from messageController: ChatMessageController) -> LazyCachedMapCollection { + private func getMessages(from messageController: ChatMessageController) -> [ChatMessage] { guard shouldRenderParentMessage else { return messageController.replies } diff --git a/StreamChat.xcodeproj/project.pbxproj b/StreamChat.xcodeproj/project.pbxproj index a29f96db9a6..40a05385c4a 100644 --- a/StreamChat.xcodeproj/project.pbxproj +++ b/StreamChat.xcodeproj/project.pbxproj @@ -439,8 +439,6 @@ 4FCCACE42BC939EB009D23E1 /* MemberList_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FCCACE32BC939EB009D23E1 /* MemberList_Tests.swift */; }; 4FD2BE502B99F68300FFC6F2 /* ReadStateHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FD2BE4F2B99F68300FFC6F2 /* ReadStateHandler.swift */; }; 4FD2BE512B99F68300FFC6F2 /* ReadStateHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FD2BE4F2B99F68300FFC6F2 /* ReadStateHandler.swift */; }; - 4FD2BE532B9AEE3500FFC6F2 /* StreamCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FD2BE522B9AEE3500FFC6F2 /* StreamCollection.swift */; }; - 4FD2BE542B9AEE3500FFC6F2 /* StreamCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FD2BE522B9AEE3500FFC6F2 /* StreamCollection.swift */; }; 4FD2BE562B9AF8A300FFC6F2 /* ChannelList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FD2BE552B9AF8A300FFC6F2 /* ChannelList.swift */; }; 4FD2BE572B9AF8A300FFC6F2 /* ChannelList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FD2BE552B9AF8A300FFC6F2 /* ChannelList.swift */; }; 4FD2BE592B9AF8B600FFC6F2 /* ChannelListState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FD2BE582B9AF8B600FFC6F2 /* ChannelListState.swift */; }; @@ -2298,7 +2296,6 @@ C121E8E1274544B100023E4C /* OptionalDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7DD8EC025E4083B0059A322 /* OptionalDecodable.swift */; }; C121E8E2274544B200023E4C /* Codable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 792A4F3D247FFDE700EAF71D /* Codable+Extensions.swift */; }; C121E8E3274544B200023E4C /* Data+Gzip.swift in Sources */ = {isa = PBXBuildFile; fileRef = 792A4F3E247FFDE700EAF71D /* Data+Gzip.swift */; }; - C121E8E4274544B200023E4C /* LazyCachedMapCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCAFE2325C44B920015AD58 /* LazyCachedMapCollection.swift */; }; C121E8E5274544B200023E4C /* Timers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 792A4F3B247FFBB400EAF71D /* Timers.swift */; }; C121E8E6274544B200023E4C /* SystemEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 797A756524814EF8003CF16D /* SystemEnvironment.swift */; }; C121E8E7274544B200023E4C /* Bundle+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 797A756724814F0D003CF16D /* Bundle+Extensions.swift */; }; @@ -2681,12 +2678,10 @@ DB3CCF3F258CF7ED009D5E99 /* ChatMessageLinkPreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB3CCF3E258CF7ED009D5E99 /* ChatMessageLinkPreviewView.swift */; }; DB70CFFB25702EB900DDF436 /* ChatMessagePopupVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB70CFFA25702EB900DDF436 /* ChatMessagePopupVC.swift */; }; DB8230F2259B8DBF00E7D7FE /* ChatMessageGiphyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8230F1259B8DBF00E7D7FE /* ChatMessageGiphyView.swift */; }; - DB842E4525C9F94C000AAC46 /* LazyCachedMapCollection_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB842E4425C9F94C000AAC46 /* LazyCachedMapCollection_Tests.swift */; }; DB9A3D562582689A00555D36 /* ChatMessageListRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A3D552582689A00555D36 /* ChatMessageListRouter.swift */; }; DBC8A4BB257E5BFB00B20A82 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DBC8A4BD257E5BFB00B20A82 /* Localizable.stringsdict */; }; DBC8A564258113F700B20A82 /* ChatThreadVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC8A563258113F700B20A82 /* ChatThreadVC.swift */; }; DBC8A5762581476E00B20A82 /* ChatMessageListVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC8A5752581476E00B20A82 /* ChatMessageListVC.swift */; }; - DBCAFE2425C44B920015AD58 /* LazyCachedMapCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCAFE2325C44B920015AD58 /* LazyCachedMapCollection.swift */; }; DBF12128258BAFC1001919C6 /* OnlyLinkTappableTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF12127258BAFC1001919C6 /* OnlyLinkTappableTextView.swift */; }; DBF17AE825D48865004517B3 /* BackgroundTaskScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF17AE725D48865004517B3 /* BackgroundTaskScheduler.swift */; }; E3B987EF2844DE1200C2E101 /* MemberRole.json in Resources */ = {isa = PBXBuildFile; fileRef = E3B987EE2844DE1200C2E101 /* MemberRole.json */; }; @@ -3443,7 +3438,6 @@ 4FC743EA2D8D9A2600E314EB /* ImageViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageViewExtensions.swift; sourceTree = ""; }; 4FCCACE32BC939EB009D23E1 /* MemberList_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberList_Tests.swift; sourceTree = ""; }; 4FD2BE4F2B99F68300FFC6F2 /* ReadStateHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadStateHandler.swift; sourceTree = ""; }; - 4FD2BE522B9AEE3500FFC6F2 /* StreamCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamCollection.swift; sourceTree = ""; }; 4FD2BE552B9AF8A300FFC6F2 /* ChannelList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelList.swift; sourceTree = ""; }; 4FD2BE582B9AF8B600FFC6F2 /* ChannelListState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelListState.swift; sourceTree = ""; }; 4FD2BE5B2B9AF8C300FFC6F2 /* ChannelListState+Observer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ChannelListState+Observer.swift"; sourceTree = ""; }; @@ -4941,12 +4935,10 @@ DB3CCF3E258CF7ED009D5E99 /* ChatMessageLinkPreviewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageLinkPreviewView.swift; sourceTree = ""; }; DB70CFFA25702EB900DDF436 /* ChatMessagePopupVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessagePopupVC.swift; sourceTree = ""; }; DB8230F1259B8DBF00E7D7FE /* ChatMessageGiphyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageGiphyView.swift; sourceTree = ""; }; - DB842E4425C9F94C000AAC46 /* LazyCachedMapCollection_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyCachedMapCollection_Tests.swift; sourceTree = ""; }; DB9A3D552582689A00555D36 /* ChatMessageListRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageListRouter.swift; sourceTree = ""; }; DBC8A4BC257E5BFB00B20A82 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; DBC8A563258113F700B20A82 /* ChatThreadVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatThreadVC.swift; sourceTree = ""; }; DBC8A5752581476E00B20A82 /* ChatMessageListVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageListVC.swift; sourceTree = ""; }; - DBCAFE2325C44B920015AD58 /* LazyCachedMapCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LazyCachedMapCollection.swift; sourceTree = ""; }; DBF12127258BAFC1001919C6 /* OnlyLinkTappableTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnlyLinkTappableTextView.swift; sourceTree = ""; }; DBF17AE725D48865004517B3 /* BackgroundTaskScheduler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskScheduler.swift; sourceTree = ""; }; E386432C2857299E00DB3FBE /* Reusable+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Reusable+Extensions.swift"; sourceTree = ""; }; @@ -6011,7 +6003,6 @@ 88EA9AD725470F6A007EE76B /* Dictionary+Extensions.swift */, 84CF9C72274D473D00BCDE2D /* EventBatcher.swift */, C173538D27D9F804008AC412 /* KeyedDecodingContainer+Array.swift */, - DBCAFE2325C44B920015AD58 /* LazyCachedMapCollection.swift */, 4FE56B8C2D5DFE3A00589F9A /* MarkdownParser.swift */, 79CD959124F9380B00E87377 /* MulticastDelegate.swift */, 881506EB258212BF0013935B /* MultipartFormData.swift */, @@ -6022,7 +6013,6 @@ C14D27B52869EEE40063F6F2 /* Sequence+CompactMapLoggingError.swift */, 4FDAD05D2BC8179E004048E8 /* StateBuilder.swift */, 7985BDA9252B1E53002B8C30 /* StreamConcurrency.swift */, - 4FD2BE522B9AEE3500FFC6F2 /* StreamCollection.swift */, 797A756524814EF8003CF16D /* SystemEnvironment.swift */, CFA41B6527DA724400427602 /* SystemEnvironment+XStreamClient.swift */, AD0F7F162B6139D500914C4C /* TextLinkDetector.swift */, @@ -7991,7 +7981,6 @@ 84ABF699274E570600EDDA68 /* EventBatcher_Tests.swift */, BCE48068C1C02C0689BEB64E /* JSONDecoder_Tests.swift */, BCE489A4B136D48249DD6969 /* JSONEncoder_Tests.swift */, - DB842E4425C9F94C000AAC46 /* LazyCachedMapCollection_Tests.swift */, AD5BCCC82AB22A6600456CD9 /* Logger_Tests.swift */, 79CD959324F9381700E87377 /* MulticastDelegate_Tests.swift */, ADEDA1F92B2BC46C00020460 /* RepeatingTimer_Tests.swift */, @@ -12019,7 +12008,6 @@ 8AAB1C6624CB39F2009B783F /* UnreadCount.swift in Sources */, 79877A282498E50D00015F8B /* UserDTO.swift in Sources */, 845CFD742BD7FA010058F691 /* PollControllerDelegate.swift in Sources */, - DBCAFE2425C44B920015AD58 /* LazyCachedMapCollection.swift in Sources */, 79280F47248515FA00CDEB89 /* ChannelEvents.swift in Sources */, 7978FBBC26E16295002CA2DF /* MessageSearchQueryDTO.swift in Sources */, DA640FBE2535CF9200D32944 /* UserListSortingKey.swift in Sources */, @@ -12157,7 +12145,6 @@ 84ABB015269F0A84003A4585 /* EventsController+Combine.swift in Sources */, 841BAA012BCE9394000C73E4 /* UpdatePollRequestBody.swift in Sources */, F670B50F24FE6EA900003B1A /* MessageEditor.swift in Sources */, - 4FD2BE532B9AEE3500FFC6F2 /* StreamCollection.swift in Sources */, 7991D83D24F7E93900D21BA3 /* ChannelListController+SwiftUI.swift in Sources */, 225D7FE225D191400094E555 /* ChatMessageImageAttachment.swift in Sources */, 8A0D64A724E57A520017A3C0 /* GuestUserTokenRequestPayload.swift in Sources */, @@ -12227,7 +12214,6 @@ A3960E0B27DA587B003AB2B0 /* RetryStrategy_Tests.swift in Sources */, AD0CC0282BDBF9DD005E2C66 /* ReactionListUpdater_Tests.swift in Sources */, 88F6DF94252C8866009A8AF0 /* ChannelMemberUpdater_Tests.swift in Sources */, - DB842E4525C9F94C000AAC46 /* LazyCachedMapCollection_Tests.swift in Sources */, 84EB4E76276A012900E47E73 /* ClientError_Tests.swift in Sources */, DA8407232525E871005A0F62 /* UserListPayload_Tests.swift in Sources */, 437FCA1926D906B20000223C /* ChatRemoteNotificationHandler_Tests.swift in Sources */, @@ -12867,7 +12853,6 @@ C121E855274544AE00023E4C /* AttachmentEndpoints.swift in Sources */, C121E856274544AE00023E4C /* ChatRemoteNotificationHandler.swift in Sources */, C121E857274544AE00023E4C /* Worker.swift in Sources */, - 4FD2BE542B9AEE3500FFC6F2 /* StreamCollection.swift in Sources */, C121E858274544AE00023E4C /* CurrentUserUpdater.swift in Sources */, AD7BE16B2C209888000A5756 /* ThreadEvents.swift in Sources */, C121E859274544AE00023E4C /* ChannelListUpdater.swift in Sources */, @@ -13138,7 +13123,6 @@ C121E8E2274544B200023E4C /* Codable+Extensions.swift in Sources */, AD1BA40B2E3A2D180092D602 /* ManualEventHandler.swift in Sources */, C121E8E3274544B200023E4C /* Data+Gzip.swift in Sources */, - C121E8E4274544B200023E4C /* LazyCachedMapCollection.swift in Sources */, 40789D3D29F6AD9C0018C2BB /* Debouncer.swift in Sources */, AD7A11CC2DEE091400B8F963 /* LocationEndpoints.swift in Sources */, AD6E32A22BBC50110073831B /* ThreadListQuery.swift in Sources */, diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/BackgroundListDatabaseObserver_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/BackgroundListDatabaseObserver_Mock.swift index 1cbf5b9b93f..629b8e16dbb 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/BackgroundListDatabaseObserver_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/BackgroundListDatabaseObserver_Mock.swift @@ -17,8 +17,8 @@ final class BackgroundListDatabaseObserver_Mock? - override var items: LazyCachedMapCollection { + var items_mock: [Item]? + override var items: [Item] { items_mock ?? super.items } } diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChannelListController_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChannelListController_Mock.swift index 94b30339690..d9fad466d86 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChannelListController_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChannelListController_Mock.swift @@ -9,11 +9,11 @@ import XCTest final class ChannelListController_Mock: ChatChannelListController, @unchecked Sendable { @Atomic var synchronize_called = false @Atomic var synchronize_callCount = 0 - @Atomic var synchronize_completion: (@MainActor(Error?) -> Void)? + @Atomic var synchronize_completion: (@MainActor (Error?) -> Void)? var channels_simulated: [ChatChannel]? - override var channels: LazyCachedMapCollection { - channels_simulated.map { $0.lazyCachedMap { $0 } } ?? super.channels + override var channels: [ChatChannel] { + channels_simulated ?? super.channels } var state_simulated: DataController.State? @@ -26,7 +26,7 @@ final class ChannelListController_Mock: ChatChannelListController, @unchecked Se super.init(query: .init(filter: .nonEmpty), client: .mock) } - override func synchronize(_ completion: (@MainActor(Error?) -> Void)? = nil) { + override func synchronize(_ completion: (@MainActor (Error?) -> Void)? = nil) { synchronize_callCount += 1 synchronize_completion = completion } diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatChannelController_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatChannelController_Mock.swift index 4c87f050850..afc7c5f5ea1 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatChannelController_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatChannelController_Mock.swift @@ -67,7 +67,7 @@ class ChatChannelController_Mock: ChatChannelController, @unchecked Sendable { restrictedVisibility: [UserId] = [], location: NewLocationInfo? = nil, extraData: [String: RawJSON] = [:], - completion: (@MainActor(Result) -> Void)? = nil + completion: (@MainActor (Result) -> Void)? = nil ) { createNewMessageCallCount += 1 } @@ -98,13 +98,13 @@ class ChatChannelController_Mock: ChatChannelController, @unchecked Sendable { } var messages_mock: [ChatMessage]? - override var messages: LazyCachedMapCollection { - messages_mock.map { $0.lazyCachedMap { $0 } } ?? super.messages + override var messages: [ChatMessage] { + messages_mock ?? super.messages } var markReadCallCount = 0 - var markRead_completion: (@MainActor(Error?) -> Void)? - override func markRead(completion: (@MainActor(Error?) -> Void)?) { + var markRead_completion: (@MainActor (Error?) -> Void)? + override func markRead(completion: (@MainActor (Error?) -> Void)?) { markReadCallCount += 1 markRead_completion = completion } @@ -116,15 +116,15 @@ class ChatChannelController_Mock: ChatChannelController, @unchecked Sendable { } var synchronize_callCount = 0 - var synchronize_completion: (@MainActor(Error?) -> Void)? - override func synchronize(_ completion: (@MainActor(Error?) -> Void)? = nil) { + var synchronize_completion: (@MainActor (Error?) -> Void)? + override func synchronize(_ completion: (@MainActor (Error?) -> Void)? = nil) { synchronize_callCount += 1 synchronize_completion = completion } var loadFirstPageCallCount = 0 var loadFirstPage_result: Error? - override func loadFirstPage(_ completion: (@MainActor(Error?) -> Void)? = nil) { + override func loadFirstPage(_ completion: (@MainActor (Error?) -> Void)? = nil) { loadFirstPageCallCount += 1 callback { completion?(self.loadFirstPage_result) @@ -135,13 +135,13 @@ class ChatChannelController_Mock: ChatChannelController, @unchecked Sendable { override func loadPageAroundMessageId( _ messageId: MessageId, limit: Int? = nil, - completion: (@MainActor(Error?) -> Void)? = nil + completion: (@MainActor (Error?) -> Void)? = nil ) { loadPageAroundMessageIdCallCount += 1 } var updateDraftMessage_callCount = 0 - var updateDraftMessage_completion: (@MainActor(Result) -> Void)? + var updateDraftMessage_completion: (@MainActor (Result) -> Void)? var updateDraftMessage_text = "" override func updateDraftMessage( @@ -152,7 +152,7 @@ class ChatChannelController_Mock: ChatChannelController, @unchecked Sendable { quotedMessageId: MessageId? = nil, command: Command? = nil, extraData: [String: RawJSON] = [:], - completion: (@MainActor(Result) -> Void)? = nil + completion: (@MainActor (Result) -> Void)? = nil ) { updateDraftMessage_text = text updateDraftMessage_callCount += 1 @@ -160,17 +160,17 @@ class ChatChannelController_Mock: ChatChannelController, @unchecked Sendable { } var deleteDraftMessage_callCount = 0 - var deleteDraftMessage_completion: (@MainActor(Error?) -> Void)? + var deleteDraftMessage_completion: (@MainActor (Error?) -> Void)? - override func deleteDraftMessage(completion: (@MainActor(Error?) -> Void)? = nil) { + override func deleteDraftMessage(completion: (@MainActor (Error?) -> Void)? = nil) { deleteDraftMessage_callCount += 1 deleteDraftMessage_completion = completion } var loadDraftMessage_callCount = 0 - var loadDraftMessage_completion: (@MainActor(Result) -> Void)? + var loadDraftMessage_completion: (@MainActor (Result) -> Void)? - override func loadDraftMessage(completion: (@MainActor(Result) -> Void)? = nil) { + override func loadDraftMessage(completion: (@MainActor (Result) -> Void)? = nil) { loadDraftMessage_callCount += 1 loadDraftMessage_completion = completion } diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatChannelListController_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatChannelListController_Mock.swift index 1b149927ed2..9405d91454b 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatChannelListController_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatChannelListController_Mock.swift @@ -17,8 +17,8 @@ class ChatChannelListController_Mock: ChatChannelListController, Spy, @unchecked } var channels_mock: [ChatChannel]? - override var channels: LazyCachedMapCollection { - channels_mock.map { $0.lazyCachedMap { $0 } } ?? super.channels + override var channels: [ChatChannel] { + channels_mock ?? super.channels } var state_mock: State? @@ -27,7 +27,7 @@ class ChatChannelListController_Mock: ChatChannelListController, Spy, @unchecked set { super.state = newValue } } - override func loadNextChannels(limit: Int?, completion: (@MainActor(Error?) -> Void)?) { + override func loadNextChannels(limit: Int?, completion: (@MainActor (Error?) -> Void)?) { loadNextChannelsCallCount += 1 loadNextChannelsIsCalled = true } diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatChannelWatcherListController_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatChannelWatcherListController_Mock.swift index 2e9e5a87876..48d1905595f 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatChannelWatcherListController_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatChannelWatcherListController_Mock.swift @@ -8,8 +8,8 @@ import XCTest /// A mock for `ChatChannelWatcherListController`. final class ChatChannelWatcherListController_Mock: ChatChannelWatcherListController, @unchecked Sendable { @Atomic var watchers_simulated: [ChatUser]? - override var watchers: LazyCachedMapCollection { - watchers_simulated.map { $0.lazyCachedMap { $0 } } ?? super.watchers + override var watchers: [ChatUser] { + watchers_simulated ?? super.watchers } @Atomic var state_simulated: DataController.State? diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatMessageController_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatMessageController_Mock.swift index 73acae3cca7..9f7e313af2f 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatMessageController_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatMessageController_Mock.swift @@ -29,8 +29,8 @@ class ChatMessageController_Mock: ChatMessageController, @unchecked Sendable { } var replies_mock: [ChatMessage]? - override var replies: LazyCachedMapCollection { - replies_mock.map { $0.lazyCachedMap { $0 } } ?? super.replies + override var replies: [ChatMessage] { + replies_mock ?? super.replies } var state_mock: State? @@ -50,18 +50,18 @@ class ChatMessageController_Mock: ChatMessageController, @unchecked Sendable { } var synchronize_callCount = 0 - var synchronize_completion: (@MainActor(Error?) -> Void)? - override func synchronize(_ completion: (@MainActor(Error?) -> Void)? = nil) { + var synchronize_completion: (@MainActor (Error?) -> Void)? + override func synchronize(_ completion: (@MainActor (Error?) -> Void)? = nil) { synchronize_callCount += 1 synchronize_completion = completion } var loadPageAroundReplyId_callCount = 0 - var loadPageAroundReplyId_completion: (@MainActor(Error?) -> Void)? + var loadPageAroundReplyId_completion: (@MainActor (Error?) -> Void)? override func loadPageAroundReplyId( _ replyId: MessageId, limit: Int? = nil, - completion: (@MainActor(Error?) -> Void)? = nil + completion: (@MainActor (Error?) -> Void)? = nil ) { loadPageAroundReplyId_callCount += 1 loadPageAroundReplyId_completion = completion diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatMessageSearchController_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatMessageSearchController_Mock.swift index 3dd269d9e5c..485de2ec2dc 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatMessageSearchController_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatMessageSearchController_Mock.swift @@ -10,8 +10,8 @@ class ChatMessageSearchController_Mock: ChatMessageSearchController, @unchecked .init(client: client ?? .mock()) } - var messages_mock: LazyCachedMapCollection? - override var messages: LazyCachedMapCollection { + var messages_mock: [ChatMessage]? + override var messages: [ChatMessage] { messages_mock ?? super.messages } @@ -26,7 +26,7 @@ class ChatMessageSearchController_Mock: ChatMessageSearchController, @unchecked } var loadNextMessagesCallCount = 0 - override func loadNextMessages(limit: Int = 25, completion: (@MainActor(Error?) -> Void)? = nil) { + override func loadNextMessages(limit: Int = 25, completion: (@MainActor (Error?) -> Void)? = nil) { loadNextMessagesCallCount += 1 callback { completion?(nil) @@ -34,14 +34,14 @@ class ChatMessageSearchController_Mock: ChatMessageSearchController, @unchecked } var searchCallCount = 0 - override func search(query: MessageSearchQuery, completion: (@MainActor(Error?) -> Void)? = nil) { + override func search(query: MessageSearchQuery, completion: (@MainActor (Error?) -> Void)? = nil) { searchCallCount += 1 callback { completion?(nil) } } - override func search(text: String, completion: (@MainActor(Error?) -> Void)? = nil) { + override func search(text: String, completion: (@MainActor (Error?) -> Void)? = nil) { searchCallCount += 1 } } diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatThreadListController_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatThreadListController_Mock.swift index 16716ab769a..0ee7ab7ece1 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatThreadListController_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatThreadListController_Mock.swift @@ -11,8 +11,8 @@ class ChatThreadListController_Mock: ChatThreadListController, @unchecked Sendab } var threads_mock: [ChatThread]? - override var threads: LazyCachedMapCollection { - threads_mock.map { $0.lazyCachedMap { $0 } } ?? super.threads + override var threads: [ChatThread] { + threads_mock ?? super.threads } var state_mock: State? @@ -21,9 +21,9 @@ class ChatThreadListController_Mock: ChatThreadListController, @unchecked Sendab set { super.state = newValue } } - var synchronize_completion: (@MainActor(Error?) -> Void)? + var synchronize_completion: (@MainActor (Error?) -> Void)? var synchronize_callCount = 0 - override func synchronize(_ completion: (@MainActor(Error?) -> Void)? = nil) { + override func synchronize(_ completion: (@MainActor (Error?) -> Void)? = nil) { synchronize_callCount += 1 synchronize_completion = completion } diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/PollController_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/PollController_Mock.swift index 277d326e93a..b516e215359 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/PollController_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/PollController_Mock.swift @@ -22,8 +22,8 @@ final class PollController_Mock: PollController, @unchecked Sendable { poll_simulated } - var ownVotes_simulated: LazyCachedMapCollection = .init([]) - override var ownVotes: LazyCachedMapCollection { + var ownVotes_simulated: [PollVote] = .init([]) + override var ownVotes: [PollVote] { ownVotes_simulated } @@ -34,8 +34,8 @@ final class PollController_Mock: PollController, @unchecked Sendable { } var synchronize_callCount = 0 - var synchronize_completion: (@MainActor(Error?) -> Void)? - override func synchronize(_ completion: (@MainActor(Error?) -> Void)? = nil) { + var synchronize_completion: (@MainActor (Error?) -> Void)? + override func synchronize(_ completion: (@MainActor (Error?) -> Void)? = nil) { synchronize_callCount += 1 synchronize_called = true synchronize_completion = completion @@ -44,7 +44,7 @@ final class PollController_Mock: PollController, @unchecked Sendable { override func castPollVote( answerText: String?, optionId: String?, - completion: (@MainActor(Error?) -> Void)? = nil + completion: (@MainActor (Error?) -> Void)? = nil ) { castPollVote_called = true castPollVote_completion_result?.invoke(with: completion) @@ -52,15 +52,15 @@ final class PollController_Mock: PollController, @unchecked Sendable { override func removePollVote( voteId: String, - completion: (@MainActor(Error?) -> Void)? = nil + completion: (@MainActor (Error?) -> Void)? = nil ) { removePollVote_called = true removePollVote_completion_result?.invoke(with: completion) } var closePoll_callCount = 0 - var closePoll_completion: (@MainActor(Error?) -> Void)? - override func closePoll(completion: (@MainActor(Error?) -> Void)? = nil) { + var closePoll_completion: (@MainActor (Error?) -> Void)? + override func closePoll(completion: (@MainActor (Error?) -> Void)? = nil) { closePoll_callCount += 1 closePoll_called = true closePoll_completion = completion @@ -70,7 +70,7 @@ final class PollController_Mock: PollController, @unchecked Sendable { text: String, position: Int? = nil, extraData: [String: RawJSON]? = nil, - completion: (@MainActor(Error?) -> Void)? = nil + completion: (@MainActor (Error?) -> Void)? = nil ) { suggestPollOption_called = true suggestPollOption_completion_result?.invoke(with: completion) diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/PollVoteListController_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/PollVoteListController_Mock.swift index 540c7c03201..95476f7b21e 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/PollVoteListController_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/PollVoteListController_Mock.swift @@ -11,8 +11,8 @@ final class PollVoteListController_Mock: PollVoteListController, @unchecked Send @Atomic var loadMoreVotes_limit: Int? @Atomic var loadMoreVotes_completion_result: Result? - var votes_simulated: LazyCachedMapCollection = .init([]) - override var votes: LazyCachedMapCollection { + var votes_simulated: [PollVote] = .init([]) + override var votes: [PollVote] { votes_simulated } @@ -22,12 +22,12 @@ final class PollVoteListController_Mock: PollVoteListController, @unchecked Send set { super.state = newValue } } - override func synchronize(_ completion: (@MainActor(Error?) -> Void)? = nil) { + override func synchronize(_ completion: (@MainActor (Error?) -> Void)? = nil) { synchronize_called = true synchronize_completion_result?.invoke(with: completion) } - override func loadMoreVotes(limit: Int? = nil, completion: (@MainActor(Error?) -> Void)? = nil) { + override func loadMoreVotes(limit: Int? = nil, completion: (@MainActor (Error?) -> Void)? = nil) { loadMoreVotes_limit = limit loadMoreVotes_completion_result?.invoke(with: completion) } diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/MemberListController/MemberListController_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/MemberListController/MemberListController_Mock.swift index 3a3b157b0dc..c1ffb10d019 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/MemberListController/MemberListController_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/MemberListController/MemberListController_Mock.swift @@ -8,8 +8,8 @@ import XCTest /// A mock for `ChatChannelMemberListController`. final class ChatChannelMemberListController_Mock: ChatChannelMemberListController, @unchecked Sendable { @Atomic var members_simulated: [ChatChannelMember]? - override var members: LazyCachedMapCollection { - members_simulated.map { $0.lazyCachedMap { $0 } } ?? super.members + override var members: [ChatChannelMember] { + members_simulated ?? super.members } @Atomic var state_simulated: DataController.State? diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/State/ChannelList_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/State/ChannelList_Mock.swift index e1cf3bb2283..dbc8da32aea 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/State/ChannelList_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/State/ChannelList_Mock.swift @@ -18,7 +18,7 @@ public class ChannelList_Mock: ChannelList, @unchecked Sendable { override init( query: ChannelListQuery, - dynamicFilter: (@Sendable(ChatChannel) -> Bool)? = nil, + dynamicFilter: (@Sendable (ChatChannel) -> Bool)? = nil, client: ChatClient, environment: ChannelList.Environment = .init() ) { @@ -31,7 +31,7 @@ public class ChannelList_Mock: ChannelList, @unchecked Sendable { } @MainActor public func simulate(channels: [ChatChannel]) async throws { - state.channels = StreamCollection(channels) + state.channels = channels } public var loadNextChannelsIsCalled = false diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/State/Chat_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/State/Chat_Mock.swift index 32ea0ef69ce..916cbabaef7 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/State/Chat_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/State/Chat_Mock.swift @@ -80,7 +80,7 @@ public extension Chat_Mock { /// Simulates the initial conditions. Setting these values doesn't trigger any observer callback. @MainActor func simulateInitial(channel: ChatChannel, messages: [ChatMessage]) { state.channel = channel - state.messages = StreamCollection(messages) + state.messages = messages } /// Simulates a change of the `channel` value. Observers are notified with the provided `change` value. @@ -98,6 +98,6 @@ public extension Chat_Mock { newMessages.append(message) } - state.messages = StreamCollection(newMessages) + state.messages = newMessages } } diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/State/MessageSearch_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/State/MessageSearch_Mock.swift index 5a764b1cd85..12956db1064 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/State/MessageSearch_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/State/MessageSearch_Mock.swift @@ -10,20 +10,20 @@ public class MessageSearch_Mock: MessageSearch, @unchecked Sendable { .init(client: client ?? .mock(bundle: Bundle(for: Self.self))) } - @MainActor public var messages_mock: StreamCollection? { + @MainActor public var messages_mock: [ChatMessage]? { didSet { - state.messages = messages_mock ?? .init([]) + state.messages = messages_mock ?? [] } } - @MainActor public var messages: StreamCollection { + @MainActor public var messages: [ChatMessage] { messages_mock ?? super.state.messages } var loadNextMessagesCallCount = 0 override public func loadMoreMessages(limit: Int? = nil) async throws -> [ChatMessage] { loadNextMessagesCallCount += 1 - return await Array(state.messages) + return await state.messages } var searchCallCount = 0 @@ -31,7 +31,7 @@ public class MessageSearch_Mock: MessageSearch, @unchecked Sendable { searchCallCount += 1 return await MainActor.run { state.messages = messages - return Array(messages) + return messages } } @@ -39,7 +39,7 @@ public class MessageSearch_Mock: MessageSearch, @unchecked Sendable { searchCallCount += 1 return await MainActor.run { state.messages = messages - return Array(messages) + return messages } } } diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/State/UserSearch_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/State/UserSearch_Mock.swift index 79a5232b7ff..47200254b1d 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/State/UserSearch_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/State/UserSearch_Mock.swift @@ -13,7 +13,7 @@ public class UserSearch_Mock: UserSearch, @unchecked Sendable { } @MainActor public func setUsers(_ users: [ChatUser]) { - state.users = StreamCollection(users) + state.users = users } override public func loadMoreUsers(limit: Int? = nil) async throws -> [ChatUser] { diff --git a/TestTools/StreamChatTestTools/SpyPattern/Spy/ChatChannelController_Spy.swift b/TestTools/StreamChatTestTools/SpyPattern/Spy/ChatChannelController_Spy.swift index 713bc6be05f..1df65151e91 100644 --- a/TestTools/StreamChatTestTools/SpyPattern/Spy/ChatChannelController_Spy.swift +++ b/TestTools/StreamChatTestTools/SpyPattern/Spy/ChatChannelController_Spy.swift @@ -13,7 +13,7 @@ final class ChatChannelController_Spy: ChatChannelController, Spy, @unchecked Se super.init(channelQuery: .init(cid: .unique), channelListQuery: nil, client: client) } - override func recoverWatchedChannel(recovery: Bool, completion: @escaping @MainActor(Error?) -> Void) { + override func recoverWatchedChannel(recovery: Bool, completion: @escaping @MainActor (Error?) -> Void) { record() callback { completion(self.watchActiveChannelError) @@ -30,8 +30,8 @@ final class ChannelControllerSpy: ChatChannelController, @unchecked Sendable { } var messages_simulated: [ChatMessage]? - override var messages: LazyCachedMapCollection { - messages_simulated.map { $0.lazyCachedMap { $0 } } ?? super.messages + override var messages: [ChatMessage] { + messages_simulated ?? super.messages } var state_simulated: DataController.State? @@ -48,7 +48,7 @@ final class ChannelControllerSpy: ChatChannelController, @unchecked Sendable { ) } - override func synchronize(_ completion: (@MainActor(Error?) -> Void)? = nil) { + override func synchronize(_ completion: (@MainActor (Error?) -> Void)? = nil) { synchronize_called = true } } diff --git a/Tests/StreamChatTests/Controllers/PollsControllers/PollVoteListController+SwiftUI_Tests.swift b/Tests/StreamChatTests/Controllers/PollsControllers/PollVoteListController+SwiftUI_Tests.swift index f29bc3626c0..4d4f27d650a 100644 --- a/Tests/StreamChatTests/Controllers/PollsControllers/PollVoteListController+SwiftUI_Tests.swift +++ b/Tests/StreamChatTests/Controllers/PollsControllers/PollVoteListController+SwiftUI_Tests.swift @@ -42,7 +42,7 @@ final class PollVoteListController_SwiftUI_Tests: iOS13TestCase { // Simulate poll vote creation let pollVote: PollVote = .unique - let votes = LazyCachedMapCollection([pollVote]) + let votes = [pollVote] voteListController.votes_simulated = votes voteListController.delegateCallback { diff --git a/Tests/StreamChatTests/Controllers/SearchControllers/UserListController/UserListController+SwiftUI_Tests.swift b/Tests/StreamChatTests/Controllers/SearchControllers/UserListController/UserListController+SwiftUI_Tests.swift index be871972b27..632006b7e8b 100644 --- a/Tests/StreamChatTests/Controllers/SearchControllers/UserListController/UserListController+SwiftUI_Tests.swift +++ b/Tests/StreamChatTests/Controllers/SearchControllers/UserListController/UserListController+SwiftUI_Tests.swift @@ -67,8 +67,8 @@ final class UserListControllerMock: ChatUserListController, @unchecked Sendable @Atomic var synchronize_called = false var users_simulated: [ChatUser]? - override var users: LazyCachedMapCollection { - users_simulated.map { $0.lazyCachedMap { $0 } } ?? super.users + override var users: [ChatUser] { + users_simulated ?? super.users } var state_simulated: DataController.State? diff --git a/Tests/StreamChatTests/Utils/LazyCachedMapCollection_Tests.swift b/Tests/StreamChatTests/Utils/LazyCachedMapCollection_Tests.swift deleted file mode 100644 index bf94edddf72..00000000000 --- a/Tests/StreamChatTests/Utils/LazyCachedMapCollection_Tests.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright © 2025 Stream.io Inc. All rights reserved. -// - -@testable import StreamChat -@testable import StreamChatTestTools -import XCTest - -final class LazyCachedMapCollection_Tests: XCTestCase { - func test_equalByTransformedContent() { - // Arrange: Prepare two lazy sequences that gives same result but have different sources and transformations - let s1 = LazyCachedMapCollection(source: [0, 2, 4], map: { $0 * 3 }) - let s2 = LazyCachedMapCollection(source: [0, 3, 6], map: { $0 * 2 }) - - // Assert: Resulting sequences are equal - XCTAssertEqual(s1, s2) - } - - func test_notLazy() { - var transformationCount = 0 - let collection = LazyCachedMapCollection(source: Array(0...10)) { item -> Int in - transformationCount += 1 - return item - } - - // Transformed on init - XCTAssertEqual(transformationCount, 11) - - transformationCount = 0 - _ = collection[1] - _ = collection[5] - XCTAssertEqual(transformationCount, 0) - } -} diff --git a/Tests/StreamChatUITests/SnapshotTests/ChatMessageList/Poll/PollResultsVoteListVC_Tests.swift b/Tests/StreamChatUITests/SnapshotTests/ChatMessageList/Poll/PollResultsVoteListVC_Tests.swift index 83a4ecfc272..21376081e3c 100644 --- a/Tests/StreamChatUITests/SnapshotTests/ChatMessageList/Poll/PollResultsVoteListVC_Tests.swift +++ b/Tests/StreamChatUITests/SnapshotTests/ChatMessageList/Poll/PollResultsVoteListVC_Tests.swift @@ -43,7 +43,7 @@ class PollVoteListController_Mock: PollVoteListController, @unchecked Sendable { } var mockedVotes: [PollVote] = [] - override var votes: LazyCachedMapCollection { - LazyCachedMapCollection(elements: mockedVotes) + override var votes: [PollVote] { + mockedVotes } } From d8d0a2a56467908023e7bf581a72f1edb8709835 Mon Sep 17 00:00:00 2001 From: Toomas Vahter Date: Fri, 10 Oct 2025 11:02:11 +0300 Subject: [PATCH 2/3] Fix linter errors --- StreamChatUITestsApp/ViewController.swift | 4 +- .../MockServer/StreamMockServer.swift | 4 +- .../Swifter/Process.swift | 4 +- .../Swifter/Scopes.swift | 254 +++++++++--------- .../Utilities/LaunchArgument.swift | 6 +- .../Extensions/Result+Extensions.swift | 2 +- .../ChatUserSearchController_Mock.swift | 4 +- .../StreamChat/Utils/EventBatcher_Mock.swift | 4 +- .../Utils/ScheduledStreamTimer_Mock.swift | 2 +- .../VoiceRecording/MockAVPlayer.swift | 2 +- .../BackgroundTaskScheduler_Mock.swift | 4 +- .../ChannelMemberListUpdater_Mock.swift | 4 +- .../EventNotificationCenter_Mock.swift | 4 +- .../Spy/AttachmentDownloader_Spy.swift | 2 +- .../Spy/AttachmentUploader_Spy.swift | 8 +- .../SpyPattern/Spy/CDNClient_Spy.swift | 8 +- .../Spy/DatabaseContainer_Spy.swift | 10 +- .../Spy/LivestreamChannelController_Spy.swift | 2 +- .../VirtualTime/VirtualTimer.swift | 2 +- .../StreamChatTestTools/Wait/WaitFor.swift | 2 +- 20 files changed, 166 insertions(+), 166 deletions(-) diff --git a/StreamChatUITestsApp/ViewController.swift b/StreamChatUITestsApp/ViewController.swift index d1d6e8bad71..d1e8e145827 100644 --- a/StreamChatUITestsApp/ViewController.swift +++ b/StreamChatUITestsApp/ViewController.swift @@ -190,7 +190,7 @@ extension ViewController { } extension StreamChatWrapper { - func connectUser(completion: @escaping @Sendable(Error?) -> Void) { + func connectUser(completion: @escaping @Sendable (Error?) -> Void) { let userCredentials = UserCredentials.default let tokenProvider = mockTokenProvider(for: userCredentials) client?.connectUser( @@ -200,7 +200,7 @@ extension StreamChatWrapper { ) } - func connectGuestUser(completion: @escaping @Sendable(Error?) -> Void) { + func connectGuestUser(completion: @escaping @Sendable (Error?) -> Void) { client?.connectGuestUser( userInfo: .init(id: "123"), completion: completion diff --git a/TestTools/StreamChatTestMockServer/MockServer/StreamMockServer.swift b/TestTools/StreamChatTestMockServer/MockServer/StreamMockServer.swift index ff8eee2cf6b..6384ea88cb8 100644 --- a/TestTools/StreamChatTestMockServer/MockServer/StreamMockServer.swift +++ b/TestTools/StreamChatTestMockServer/MockServer/StreamMockServer.swift @@ -8,9 +8,9 @@ import XCTest public final class StreamMockServer { // Delays all HTTP responses by given time interval, 0 by default - public static nonisolated(unsafe) var httpResponseDelay: TimeInterval = 0.0 + public nonisolated(unsafe) static var httpResponseDelay: TimeInterval = 0.0 // Waits for all HTTP and Websocket responses during given time interval, 10 by default - public static nonisolated(unsafe) var waitTimeout = 10.0 + public nonisolated(unsafe) static var waitTimeout = 10.0 // Expires JWT after given timeout if `MOCK_JWT environment variable is provided public static let jwtTimeout: UInt32 = 5 diff --git a/TestTools/StreamChatTestMockServer/Swifter/Process.swift b/TestTools/StreamChatTestMockServer/Swifter/Process.swift index da365780476..41ad98ee82b 100644 --- a/TestTools/StreamChatTestMockServer/Swifter/Process.swift +++ b/TestTools/StreamChatTestMockServer/Swifter/Process.swift @@ -19,8 +19,8 @@ public class Process { #endif } - private static nonisolated(unsafe) var signalsWatchers = [(Int32) -> Void]() - private static nonisolated(unsafe) var signalsObserved = false + private nonisolated(unsafe) static var signalsWatchers = [(Int32) -> Void]() + private nonisolated(unsafe) static var signalsObserved = false public static func watchSignals(_ callback: @escaping (Int32) -> Void) { if !signalsObserved { diff --git a/TestTools/StreamChatTestMockServer/Swifter/Scopes.swift b/TestTools/StreamChatTestMockServer/Swifter/Scopes.swift index ff63ff1a463..8dc439442f1 100644 --- a/TestTools/StreamChatTestMockServer/Swifter/Scopes.swift +++ b/TestTools/StreamChatTestMockServer/Swifter/Scopes.swift @@ -17,133 +17,133 @@ public func scopes(_ scope: @escaping Closure) -> ((HttpRequest) -> HttpResponse public typealias Closure = () -> Void -nonisolated(unsafe) public var idd: String? -nonisolated(unsafe) public var dir: String? -nonisolated(unsafe) public var rel: String? -nonisolated(unsafe) public var rev: String? -nonisolated(unsafe) public var alt: String? -nonisolated(unsafe) public var forr: String? -nonisolated(unsafe) public var src: String? -nonisolated(unsafe) public var type: String? -nonisolated(unsafe) public var href: String? -nonisolated(unsafe) public var text: String? -nonisolated(unsafe) public var abbr: String? -nonisolated(unsafe) public var size: String? -nonisolated(unsafe) public var face: String? -nonisolated(unsafe) public var char: String? -nonisolated(unsafe) public var cite: String? -nonisolated(unsafe) public var span: String? -nonisolated(unsafe) public var data: String? -nonisolated(unsafe) public var axis: String? -nonisolated(unsafe) public var Name: String? -nonisolated(unsafe) public var name: String? -nonisolated(unsafe) public var code: String? -nonisolated(unsafe) public var link: String? -nonisolated(unsafe) public var lang: String? -nonisolated(unsafe) public var cols: String? -nonisolated(unsafe) public var rows: String? -nonisolated(unsafe) public var ismap: String? -nonisolated(unsafe) public var shape: String? -nonisolated(unsafe) public var style: String? -nonisolated(unsafe) public var alink: String? -nonisolated(unsafe) public var width: String? -nonisolated(unsafe) public var rules: String? -nonisolated(unsafe) public var align: String? -nonisolated(unsafe) public var frame: String? -nonisolated(unsafe) public var vlink: String? -nonisolated(unsafe) public var deferr: String? -nonisolated(unsafe) public var color: String? -nonisolated(unsafe) public var media: String? -nonisolated(unsafe) public var title: String? -nonisolated(unsafe) public var scope: String? -nonisolated(unsafe) public var classs: String? -nonisolated(unsafe) public var manifest: String? -nonisolated(unsafe) public var value: String? -nonisolated(unsafe) public var clear: String? -nonisolated(unsafe) public var start: String? -nonisolated(unsafe) public var label: String? -nonisolated(unsafe) public var action: String? -nonisolated(unsafe) public var height: String? -nonisolated(unsafe) public var method: String? -nonisolated(unsafe) public var acceptt: String? -nonisolated(unsafe) public var object: String? -nonisolated(unsafe) public var scheme: String? -nonisolated(unsafe) public var coords: String? -nonisolated(unsafe) public var usemap: String? -nonisolated(unsafe) public var onblur: String? -nonisolated(unsafe) public var nohref: String? -nonisolated(unsafe) public var nowrap: String? -nonisolated(unsafe) public var hspace: String? -nonisolated(unsafe) public var border: String? -nonisolated(unsafe) public var valign: String? -nonisolated(unsafe) public var vspace: String? -nonisolated(unsafe) public var onload: String? -nonisolated(unsafe) public var target: String? -nonisolated(unsafe) public var prompt: String? -nonisolated(unsafe) public var onfocus: String? -nonisolated(unsafe) public var enctype: String? -nonisolated(unsafe) public var onclick: String? -nonisolated(unsafe) public var ontouchstart: String? -nonisolated(unsafe) public var onkeyup: String? -nonisolated(unsafe) public var profile: String? -nonisolated(unsafe) public var version: String? -nonisolated(unsafe) public var onreset: String? -nonisolated(unsafe) public var charset: String? -nonisolated(unsafe) public var standby: String? -nonisolated(unsafe) public var colspan: String? -nonisolated(unsafe) public var charoff: String? -nonisolated(unsafe) public var classid: String? -nonisolated(unsafe) public var compact: String? -nonisolated(unsafe) public var declare: String? -nonisolated(unsafe) public var rowspan: String? -nonisolated(unsafe) public var checked: String? -nonisolated(unsafe) public var archive: String? -nonisolated(unsafe) public var bgcolor: String? -nonisolated(unsafe) public var content: String? -nonisolated(unsafe) public var noshade: String? -nonisolated(unsafe) public var summary: String? -nonisolated(unsafe) public var headers: String? -nonisolated(unsafe) public var onselect: String? -nonisolated(unsafe) public var readonly: String? -nonisolated(unsafe) public var tabindex: String? -nonisolated(unsafe) public var onchange: String? -nonisolated(unsafe) public var noresize: String? -nonisolated(unsafe) public var disabled: String? -nonisolated(unsafe) public var longdesc: String? -nonisolated(unsafe) public var codebase: String? -nonisolated(unsafe) public var language: String? -nonisolated(unsafe) public var datetime: String? -nonisolated(unsafe) public var selected: String? -nonisolated(unsafe) public var hreflang: String? -nonisolated(unsafe) public var onsubmit: String? -nonisolated(unsafe) public var multiple: String? -nonisolated(unsafe) public var onunload: String? -nonisolated(unsafe) public var codetype: String? -nonisolated(unsafe) public var scrolling: String? -nonisolated(unsafe) public var onkeydown: String? -nonisolated(unsafe) public var maxlength: String? -nonisolated(unsafe) public var valuetype: String? -nonisolated(unsafe) public var accesskey: String? -nonisolated(unsafe) public var onmouseup: String? -nonisolated(unsafe) public var autofocus: String? -nonisolated(unsafe) public var onkeypress: String? -nonisolated(unsafe) public var ondblclick: String? -nonisolated(unsafe) public var onmouseout: String? -nonisolated(unsafe) public var httpEquiv: String? -nonisolated(unsafe) public var dataText: String? -nonisolated(unsafe) public var background: String? -nonisolated(unsafe) public var onmousemove: String? -nonisolated(unsafe) public var onmouseover: String? -nonisolated(unsafe) public var cellpadding: String? -nonisolated(unsafe) public var onmousedown: String? -nonisolated(unsafe) public var frameborder: String? -nonisolated(unsafe) public var marginwidth: String? -nonisolated(unsafe) public var cellspacing: String? -nonisolated(unsafe) public var placeholder: String? -nonisolated(unsafe) public var marginheight: String? -nonisolated(unsafe) public var acceptCharset: String? - -nonisolated(unsafe) public var inner: String? +public nonisolated(unsafe) var idd: String? +public nonisolated(unsafe) var dir: String? +public nonisolated(unsafe) var rel: String? +public nonisolated(unsafe) var rev: String? +public nonisolated(unsafe) var alt: String? +public nonisolated(unsafe) var forr: String? +public nonisolated(unsafe) var src: String? +public nonisolated(unsafe) var type: String? +public nonisolated(unsafe) var href: String? +public nonisolated(unsafe) var text: String? +public nonisolated(unsafe) var abbr: String? +public nonisolated(unsafe) var size: String? +public nonisolated(unsafe) var face: String? +public nonisolated(unsafe) var char: String? +public nonisolated(unsafe) var cite: String? +public nonisolated(unsafe) var span: String? +public nonisolated(unsafe) var data: String? +public nonisolated(unsafe) var axis: String? +public nonisolated(unsafe) var Name: String? +public nonisolated(unsafe) var name: String? +public nonisolated(unsafe) var code: String? +public nonisolated(unsafe) var link: String? +public nonisolated(unsafe) var lang: String? +public nonisolated(unsafe) var cols: String? +public nonisolated(unsafe) var rows: String? +public nonisolated(unsafe) var ismap: String? +public nonisolated(unsafe) var shape: String? +public nonisolated(unsafe) var style: String? +public nonisolated(unsafe) var alink: String? +public nonisolated(unsafe) var width: String? +public nonisolated(unsafe) var rules: String? +public nonisolated(unsafe) var align: String? +public nonisolated(unsafe) var frame: String? +public nonisolated(unsafe) var vlink: String? +public nonisolated(unsafe) var deferr: String? +public nonisolated(unsafe) var color: String? +public nonisolated(unsafe) var media: String? +public nonisolated(unsafe) var title: String? +public nonisolated(unsafe) var scope: String? +public nonisolated(unsafe) var classs: String? +public nonisolated(unsafe) var manifest: String? +public nonisolated(unsafe) var value: String? +public nonisolated(unsafe) var clear: String? +public nonisolated(unsafe) var start: String? +public nonisolated(unsafe) var label: String? +public nonisolated(unsafe) var action: String? +public nonisolated(unsafe) var height: String? +public nonisolated(unsafe) var method: String? +public nonisolated(unsafe) var acceptt: String? +public nonisolated(unsafe) var object: String? +public nonisolated(unsafe) var scheme: String? +public nonisolated(unsafe) var coords: String? +public nonisolated(unsafe) var usemap: String? +public nonisolated(unsafe) var onblur: String? +public nonisolated(unsafe) var nohref: String? +public nonisolated(unsafe) var nowrap: String? +public nonisolated(unsafe) var hspace: String? +public nonisolated(unsafe) var border: String? +public nonisolated(unsafe) var valign: String? +public nonisolated(unsafe) var vspace: String? +public nonisolated(unsafe) var onload: String? +public nonisolated(unsafe) var target: String? +public nonisolated(unsafe) var prompt: String? +public nonisolated(unsafe) var onfocus: String? +public nonisolated(unsafe) var enctype: String? +public nonisolated(unsafe) var onclick: String? +public nonisolated(unsafe) var ontouchstart: String? +public nonisolated(unsafe) var onkeyup: String? +public nonisolated(unsafe) var profile: String? +public nonisolated(unsafe) var version: String? +public nonisolated(unsafe) var onreset: String? +public nonisolated(unsafe) var charset: String? +public nonisolated(unsafe) var standby: String? +public nonisolated(unsafe) var colspan: String? +public nonisolated(unsafe) var charoff: String? +public nonisolated(unsafe) var classid: String? +public nonisolated(unsafe) var compact: String? +public nonisolated(unsafe) var declare: String? +public nonisolated(unsafe) var rowspan: String? +public nonisolated(unsafe) var checked: String? +public nonisolated(unsafe) var archive: String? +public nonisolated(unsafe) var bgcolor: String? +public nonisolated(unsafe) var content: String? +public nonisolated(unsafe) var noshade: String? +public nonisolated(unsafe) var summary: String? +public nonisolated(unsafe) var headers: String? +public nonisolated(unsafe) var onselect: String? +public nonisolated(unsafe) var readonly: String? +public nonisolated(unsafe) var tabindex: String? +public nonisolated(unsafe) var onchange: String? +public nonisolated(unsafe) var noresize: String? +public nonisolated(unsafe) var disabled: String? +public nonisolated(unsafe) var longdesc: String? +public nonisolated(unsafe) var codebase: String? +public nonisolated(unsafe) var language: String? +public nonisolated(unsafe) var datetime: String? +public nonisolated(unsafe) var selected: String? +public nonisolated(unsafe) var hreflang: String? +public nonisolated(unsafe) var onsubmit: String? +public nonisolated(unsafe) var multiple: String? +public nonisolated(unsafe) var onunload: String? +public nonisolated(unsafe) var codetype: String? +public nonisolated(unsafe) var scrolling: String? +public nonisolated(unsafe) var onkeydown: String? +public nonisolated(unsafe) var maxlength: String? +public nonisolated(unsafe) var valuetype: String? +public nonisolated(unsafe) var accesskey: String? +public nonisolated(unsafe) var onmouseup: String? +public nonisolated(unsafe) var autofocus: String? +public nonisolated(unsafe) var onkeypress: String? +public nonisolated(unsafe) var ondblclick: String? +public nonisolated(unsafe) var onmouseout: String? +public nonisolated(unsafe) var httpEquiv: String? +public nonisolated(unsafe) var dataText: String? +public nonisolated(unsafe) var background: String? +public nonisolated(unsafe) var onmousemove: String? +public nonisolated(unsafe) var onmouseover: String? +public nonisolated(unsafe) var cellpadding: String? +public nonisolated(unsafe) var onmousedown: String? +public nonisolated(unsafe) var frameborder: String? +public nonisolated(unsafe) var marginwidth: String? +public nonisolated(unsafe) var cellspacing: String? +public nonisolated(unsafe) var placeholder: String? +public nonisolated(unsafe) var marginheight: String? +public nonisolated(unsafe) var acceptCharset: String? + +public nonisolated(unsafe) var inner: String? public func a(_ closure: Closure) { element("a", closure) } public func b(_ closure: Closure) { element("b", closure) } diff --git a/TestTools/StreamChatTestMockServer/Utilities/LaunchArgument.swift b/TestTools/StreamChatTestMockServer/Utilities/LaunchArgument.swift index 3a41e572d77..1799e4511f0 100644 --- a/TestTools/StreamChatTestMockServer/Utilities/LaunchArgument.swift +++ b/TestTools/StreamChatTestMockServer/Utilities/LaunchArgument.swift @@ -6,9 +6,9 @@ import Foundation import XCTest public enum MockServerConfiguration { - public static nonisolated(unsafe) var port: UInt16 = UInt16(Int.random(in: 61000..<62000)) - public static nonisolated(unsafe) var websocketHost = "ws://localhost" - public static nonisolated(unsafe) var httpHost = "http://localhost" + public nonisolated(unsafe) static var port: UInt16 = UInt16(Int.random(in: 61000..<62000)) + public nonisolated(unsafe) static var websocketHost = "ws://localhost" + public nonisolated(unsafe) static var httpHost = "http://localhost" } public enum EnvironmentVariable: String { diff --git a/TestTools/StreamChatTestTools/Extensions/Result+Extensions.swift b/TestTools/StreamChatTestTools/Extensions/Result+Extensions.swift index 77a624c430f..5a6e0bf8871 100644 --- a/TestTools/StreamChatTestTools/Extensions/Result+Extensions.swift +++ b/TestTools/StreamChatTestTools/Extensions/Result+Extensions.swift @@ -21,7 +21,7 @@ extension Result where Success == Void { } } - func invoke(with completion: (@MainActor(Error?) -> Void)? = nil) { + func invoke(with completion: (@MainActor (Error?) -> Void)? = nil) { StreamConcurrency.onMain { switch self { case .success: diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatUserSearchController_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatUserSearchController_Mock.swift index 53313cce364..77b8065b261 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatUserSearchController_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatUserSearchController_Mock.swift @@ -17,14 +17,14 @@ class ChatUserSearchController_Mock: ChatUserSearchController, @unchecked Sendab users_mock ?? super.userArray } - override func search(query: UserListQuery, completion: (@MainActor(Error?) -> Void)? = nil) { + override func search(query: UserListQuery, completion: (@MainActor (Error?) -> Void)? = nil) { searchCallCount += 1 callback { completion?(nil) } } - override func search(term: String?, completion: (@MainActor(Error?) -> Void)? = nil) { + override func search(term: String?, completion: (@MainActor (Error?) -> Void)? = nil) { searchCallCount += 1 users_mock = users_mock?.filter { user in user.name?.contains(term ?? "") ?? true diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Utils/EventBatcher_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Utils/EventBatcher_Mock.swift index 992ee6c78b1..533112cd452 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Utils/EventBatcher_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Utils/EventBatcher_Mock.swift @@ -8,12 +8,12 @@ import Foundation final class EventBatcher_Mock: EventBatcher, @unchecked Sendable { var currentBatch: [Event] = [] - let handler: (_ batch: [Event], _ completion: @escaping @Sendable() -> Void) -> Void + let handler: (_ batch: [Event], _ completion: @escaping @Sendable () -> Void) -> Void init( period: TimeInterval = 0, timerType: StreamChat.Timer.Type = DefaultTimer.self, - handler: @escaping (_ batch: [Event], _ completion: @escaping @Sendable() -> Void) -> Void + handler: @escaping (_ batch: [Event], _ completion: @escaping @Sendable () -> Void) -> Void ) { self.handler = handler } diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Utils/ScheduledStreamTimer_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Utils/ScheduledStreamTimer_Mock.swift index e9b95c4007e..997a3456a22 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Utils/ScheduledStreamTimer_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Utils/ScheduledStreamTimer_Mock.swift @@ -10,7 +10,7 @@ public final class ScheduledStreamTimer_Mock: StreamTimer { public var startCallCount: Int = 0 public var isRunning: Bool = false - public var onChange: (@Sendable() -> Void)? + public var onChange: (@Sendable () -> Void)? public init() {} diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/VoiceRecording/MockAVPlayer.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/VoiceRecording/MockAVPlayer.swift index e439099cc67..bdfdba773a8 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/VoiceRecording/MockAVPlayer.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/VoiceRecording/MockAVPlayer.swift @@ -55,7 +55,7 @@ public class MockAVPlayer: AVPlayer { to time: CMTime, toleranceBefore: CMTime, toleranceAfter: CMTime, - completionHandler: @escaping @Sendable(Bool) -> Void + completionHandler: @escaping @Sendable (Bool) -> Void ) { StreamConcurrency.onMain { seekWasCalledWithTime = time diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/WebSocketClient/BackgroundTaskScheduler_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/WebSocketClient/BackgroundTaskScheduler_Mock.swift index 5b70e97ca6e..f47b2acc4cf 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/WebSocketClient/BackgroundTaskScheduler_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/WebSocketClient/BackgroundTaskScheduler_Mock.swift @@ -15,9 +15,9 @@ final class BackgroundTaskScheduler_Mock: BackgroundTaskScheduler, @unchecked Se } var beginBackgroundTask_called: Bool = false - var beginBackgroundTask_expirationHandler: (@MainActor() -> Void)? + var beginBackgroundTask_expirationHandler: (@MainActor () -> Void)? var beginBackgroundTask_returns: Bool = true - func beginTask(expirationHandler: (@MainActor() -> Void)?) -> Bool { + func beginTask(expirationHandler: (@MainActor () -> Void)?) -> Bool { beginBackgroundTask_called = true beginBackgroundTask_expirationHandler = expirationHandler return beginBackgroundTask_returns diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/ChannelMemberListUpdater_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/ChannelMemberListUpdater_Mock.swift index be263b82b9e..dfd885d726d 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/ChannelMemberListUpdater_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/ChannelMemberListUpdater_Mock.swift @@ -8,14 +8,14 @@ import XCTest /// Mock implementation of `ChannelMemberListUpdater` final class ChannelMemberListUpdater_Mock: ChannelMemberListUpdater, @unchecked Sendable { @Atomic var load_query: ChannelMemberListQuery? - @Atomic var load_completion: (@Sendable(Result<[ChatChannelMember], Error>) -> Void)? + @Atomic var load_completion: (@Sendable (Result<[ChatChannelMember], Error>) -> Void)? func cleanUp() { load_query = nil load_completion = nil } - override func load(_ query: ChannelMemberListQuery, completion: (@Sendable(Result<[ChatChannelMember], Error>) -> Void)? = nil) { + override func load(_ query: ChannelMemberListQuery, completion: (@Sendable (Result<[ChatChannelMember], Error>) -> Void)? = nil) { load_query = query load_completion = completion } diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/EventNotificationCenter_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/EventNotificationCenter_Mock.swift index 87f70c7a457..d2149d4beb9 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/EventNotificationCenter_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Workers/EventNotificationCenter_Mock.swift @@ -13,7 +13,7 @@ final class EventNotificationCenter_Mock: EventNotificationCenter, @unchecked Se var newMessageIdsMock: Set? - lazy var mock_process = MockFunc<([Event], Bool, (@Sendable() -> Void)?), Void>.mock(for: process) + lazy var mock_process = MockFunc<([Event], Bool, (@Sendable () -> Void)?), Void>.mock(for: process) var mock_processCalledWithEvents: [Event] = [] var registerManualEventHandling_calledWith: ChannelId? @@ -35,7 +35,7 @@ final class EventNotificationCenter_Mock: EventNotificationCenter, @unchecked Se override func process( _ events: [Event], postNotifications: Bool = true, - completion: (@Sendable() -> Void)? = nil + completion: (@Sendable () -> Void)? = nil ) { super.process(events, postNotifications: postNotifications, completion: completion) diff --git a/TestTools/StreamChatTestTools/SpyPattern/Spy/AttachmentDownloader_Spy.swift b/TestTools/StreamChatTestTools/SpyPattern/Spy/AttachmentDownloader_Spy.swift index 332e4ea0ff0..3cc63ba303c 100644 --- a/TestTools/StreamChatTestTools/SpyPattern/Spy/AttachmentDownloader_Spy.swift +++ b/TestTools/StreamChatTestTools/SpyPattern/Spy/AttachmentDownloader_Spy.swift @@ -10,7 +10,7 @@ final class AttachmentDownloader_Spy: AttachmentDownloader, Spy { @Atomic var downloadAttachmentProgress: Double? @Atomic var downloadAttachmentResult: Error? - func download(from remoteURL: URL, to localURL: URL, progress: (@Sendable(Double) -> Void)?, completion: @escaping @Sendable((any Error)?) -> Void) { + func download(from remoteURL: URL, to localURL: URL, progress: (@Sendable (Double) -> Void)?, completion: @escaping @Sendable ((any Error)?) -> Void) { record() if let downloadAttachmentProgress { progress?(downloadAttachmentProgress) diff --git a/TestTools/StreamChatTestTools/SpyPattern/Spy/AttachmentUploader_Spy.swift b/TestTools/StreamChatTestTools/SpyPattern/Spy/AttachmentUploader_Spy.swift index d614f644243..f3c5e9aff13 100644 --- a/TestTools/StreamChatTestTools/SpyPattern/Spy/AttachmentUploader_Spy.swift +++ b/TestTools/StreamChatTestTools/SpyPattern/Spy/AttachmentUploader_Spy.swift @@ -13,8 +13,8 @@ final class AttachmentUploader_Spy: AttachmentUploader, Spy, @unchecked Sendable func upload( _ attachment: AnyChatMessageAttachment, - progress: (@Sendable(Double) -> Void)?, - completion: @escaping @Sendable(Result) -> Void + progress: (@Sendable (Double) -> Void)?, + completion: @escaping @Sendable (Result) -> Void ) { record() @@ -31,8 +31,8 @@ final class AttachmentUploader_Spy: AttachmentUploader, Spy, @unchecked Sendable func uploadStandaloneAttachment( _ attachment: StreamAttachment, - progress: (@Sendable(Double) -> Void)?, - completion: @escaping @Sendable(Result) -> Void + progress: (@Sendable (Double) -> Void)?, + completion: @escaping @Sendable (Result) -> Void ) { record() diff --git a/TestTools/StreamChatTestTools/SpyPattern/Spy/CDNClient_Spy.swift b/TestTools/StreamChatTestTools/SpyPattern/Spy/CDNClient_Spy.swift index 1b8c4b8ea15..b6a840e0f45 100644 --- a/TestTools/StreamChatTestTools/SpyPattern/Spy/CDNClient_Spy.swift +++ b/TestTools/StreamChatTestTools/SpyPattern/Spy/CDNClient_Spy.swift @@ -14,8 +14,8 @@ final class CDNClient_Spy: CDNClient, Spy, @unchecked Sendable { func uploadAttachment( _ attachment: AnyChatMessageAttachment, - progress: (@Sendable(Double) -> Void)?, - completion: @escaping @Sendable(Result) -> Void + progress: (@Sendable (Double) -> Void)?, + completion: @escaping @Sendable (Result) -> Void ) { record() if let uploadAttachmentProgress = uploadAttachmentProgress { @@ -31,8 +31,8 @@ final class CDNClient_Spy: CDNClient, Spy, @unchecked Sendable { func uploadStandaloneAttachment( _ attachment: StreamAttachment, - progress: (@Sendable(Double) -> Void)?, - completion: @escaping @Sendable(Result) -> Void + progress: (@Sendable (Double) -> Void)?, + completion: @escaping @Sendable (Result) -> Void ) { record() if let uploadAttachmentProgress = uploadAttachmentProgress { diff --git a/TestTools/StreamChatTestTools/SpyPattern/Spy/DatabaseContainer_Spy.swift b/TestTools/StreamChatTestTools/SpyPattern/Spy/DatabaseContainer_Spy.swift index a35cb4571b3..dcbd35c0635 100644 --- a/TestTools/StreamChatTestTools/SpyPattern/Spy/DatabaseContainer_Spy.swift +++ b/TestTools/StreamChatTestTools/SpyPattern/Spy/DatabaseContainer_Spy.swift @@ -127,15 +127,15 @@ public final class DatabaseContainer_Spy: DatabaseContainer, Spy, @unchecked Sen super.recreatePersistentStore(completion: completion) } - override public func write(_ actions: @escaping @Sendable(DatabaseSession) throws -> Void, completion: @escaping @Sendable(Error?) -> Void) { + override public func write(_ actions: @escaping @Sendable (DatabaseSession) throws -> Void, completion: @escaping @Sendable (Error?) -> Void) { record() - let wrappedActions: (@Sendable(DatabaseSession) throws -> Void) = { session in + let wrappedActions: (@Sendable (DatabaseSession) throws -> Void) = { session in self.isWriteSessionInProgress = true try actions(self.sessionMock ?? session) self.isWriteSessionInProgress = false } - let completion: @Sendable(Error?) -> Void = { error in + let completion: @Sendable (Error?) -> Void = { error in completion(error) self._writeSessionCounter { $0 += 1 } self.didWrite?() @@ -159,7 +159,7 @@ public final class DatabaseContainer_Spy: DatabaseContainer, Spy, @unchecked Sen extension DatabaseContainer { /// Reads changes from the DB synchronously. Only for test purposes! - func readSynchronously(_ actions: @escaping @Sendable(DatabaseSession) throws -> T) throws -> T { + func readSynchronously(_ actions: @escaping @Sendable (DatabaseSession) throws -> T) throws -> T { let result = try waitFor { completion in self.read(actions, completion: completion) } @@ -172,7 +172,7 @@ extension DatabaseContainer { } /// Writes changes to the DB synchronously. Only for test purposes! - func writeSynchronously(_ actions: @escaping @Sendable(DatabaseSession) throws -> Void) throws { + func writeSynchronously(_ actions: @escaping @Sendable (DatabaseSession) throws -> Void) throws { let error = try waitFor { completion in self.write(actions, completion: completion) } diff --git a/TestTools/StreamChatTestTools/SpyPattern/Spy/LivestreamChannelController_Spy.swift b/TestTools/StreamChatTestTools/SpyPattern/Spy/LivestreamChannelController_Spy.swift index db7a470279d..c3cf59109df 100644 --- a/TestTools/StreamChatTestTools/SpyPattern/Spy/LivestreamChannelController_Spy.swift +++ b/TestTools/StreamChatTestTools/SpyPattern/Spy/LivestreamChannelController_Spy.swift @@ -13,7 +13,7 @@ final class LivestreamChannelController_Spy: LivestreamChannelController, Spy, @ super.init(channelQuery: .init(cid: .unique), client: client) } - override func startWatching(isInRecoveryMode: Bool, completion: (@MainActor(Error?) -> Void)? = nil) { + override func startWatching(isInRecoveryMode: Bool, completion: (@MainActor (Error?) -> Void)? = nil) { record() StreamConcurrency.onMain { completion?(startWatchingError) diff --git a/TestTools/StreamChatTestTools/VirtualTime/VirtualTimer.swift b/TestTools/StreamChatTestTools/VirtualTime/VirtualTimer.swift index 7ca1c1cb6d9..090a1dd204e 100644 --- a/TestTools/StreamChatTestTools/VirtualTime/VirtualTimer.swift +++ b/TestTools/StreamChatTestTools/VirtualTime/VirtualTimer.swift @@ -6,7 +6,7 @@ import Foundation @testable import StreamChat struct VirtualTimeTimer: StreamChat.Timer { - static nonisolated(unsafe) var time: VirtualTime! + nonisolated(unsafe) static var time: VirtualTime! static func invalidate() { time.invalidate() diff --git a/TestTools/StreamChatTestTools/Wait/WaitFor.swift b/TestTools/StreamChatTestTools/Wait/WaitFor.swift index c5d063c7316..dad08cd6036 100644 --- a/TestTools/StreamChatTestTools/Wait/WaitFor.swift +++ b/TestTools/StreamChatTestTools/Wait/WaitFor.swift @@ -33,7 +33,7 @@ public func waitFor( timeout: TimeInterval = waitForTimeout, file: StaticString = #filePath, line: UInt = #line, - _ action: (_ done: @escaping @Sendable(T) -> Void) -> Void + _ action: (_ done: @escaping @Sendable (T) -> Void) -> Void ) throws -> T { let expectation = XCTestExpectation(description: "Action completed") nonisolated(unsafe) var result: T? From 97c8878ad229b4db20f0ce6e9a97e018ad0968c4 Mon Sep 17 00:00:00 2001 From: Toomas Vahter Date: Fri, 10 Oct 2025 11:06:24 +0300 Subject: [PATCH 3/3] Merge issue --- .../Controllers/MessageController/MessageController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/StreamChat/Controllers/MessageController/MessageController.swift b/Sources/StreamChat/Controllers/MessageController/MessageController.swift index 26a41b4f821..377ba29ae7d 100644 --- a/Sources/StreamChat/Controllers/MessageController/MessageController.swift +++ b/Sources/StreamChat/Controllers/MessageController/MessageController.swift @@ -363,7 +363,7 @@ public class ChatMessageController: DataController, DelegateCallable, DataStoreP /// - Parameter completion: The completion. Will be called on a **callbackQueue** when the network request is finished. /// If request fails, the completion will be called with an error. /// - public func deleteMessageForMe(completion: ((Error?) -> Void)? = nil) { + public func deleteMessageForMe(completion: (@MainActor (Error?) -> Void)? = nil) { messageUpdater.deleteMessage( messageId: messageId, hard: false,