From 18f47dcb40e59f2ffac2a29fa435c506cd4564f7 Mon Sep 17 00:00:00 2001 From: Nuno Vieira Date: Thu, 13 Nov 2025 17:16:52 +0000 Subject: [PATCH 1/3] Fix crash in `ChatChannelViewModel.handleMessageAppear()` --- .../ChatChannel/ChatChannelViewModel.swift | 3 ++- .../ChatChannelViewModel_Tests.swift | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift b/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift index 5b40308e..44703fe8 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift @@ -50,7 +50,7 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource { private var channelName = "" private var onlineIndicatorShown = false private var lastReadMessageId: String? - var throttler = Throttler(interval: 3, broadcastLatestEvent: true) + var throttler = Throttler(interval: 3, broadcastLatestEvent: true, queue: .main) public var channelController: ChatChannelController public var messageController: ChatMessageController? @@ -833,6 +833,7 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource { } deinit { + throttler.cancel() messageCachingUtils.clearCache() if messageController == nil { utils.channelControllerFactory.clearCurrentController() diff --git a/StreamChatSwiftUITests/Tests/ChatChannel/ChatChannelViewModel_Tests.swift b/StreamChatSwiftUITests/Tests/ChatChannel/ChatChannelViewModel_Tests.swift index ace127d7..8ac70038 100644 --- a/StreamChatSwiftUITests/Tests/ChatChannel/ChatChannelViewModel_Tests.swift +++ b/StreamChatSwiftUITests/Tests/ChatChannel/ChatChannelViewModel_Tests.swift @@ -772,6 +772,31 @@ class ChatChannelViewModel_Tests: StreamChatTestCase { XCTAssertEqual(0, channelController.markReadCallCount) } + func test_chatChannelVM_handleMessageAppear_doesNotCrashWhenDeallocated() { + let message = ChatMessage.mock() + let channelController = makeChannelController(messages: [message]) + channelController.hasLoadedAllNextMessages_mock = nil + channelController.channel_mock = .mock( + cid: .unique, + unreadCount: ChannelUnreadCount(messages: 1, mentions: 0) + ) + + for _ in 0..<1000 { + autoreleasepool { + let viewModel = ChatChannelViewModel(channelController: channelController) + viewModel.handleMessageAppear(index: 0, scrollDirection: .down) + viewModel.handleMessageAppear(index: 0, scrollDirection: .down) + viewModel.handleMessageAppear(index: 0, scrollDirection: .down) + viewModel.handleMessageAppear(index: 0, scrollDirection: .down) + viewModel.handleMessageAppear(index: 0, scrollDirection: .down) + viewModel.handleMessageAppear(index: 0, scrollDirection: .down) + } + } + + // Then - Should not crash + XCTAssert(true) + } + // MARK: - highlightMessage Tests func test_highlightMessage_highlightsWhenSkipHighlightMessageIdIsNotSet() { From 26bb4b780180b76ea92b5d5b85b2f38581f76800 Mon Sep 17 00:00:00 2001 From: Nuno Vieira Date: Thu, 13 Nov 2025 17:17:27 +0000 Subject: [PATCH 2/3] Remove unecessary call when leaving the channel view in a mid page --- .../StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift | 3 --- 1 file changed, 3 deletions(-) diff --git a/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift b/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift index 44703fe8..5e5d90c5 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift @@ -839,9 +839,6 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource { utils.channelControllerFactory.clearCurrentController() cleanupAudioPlayer() ImageCache.shared.trim(toCost: utils.messageListConfig.cacheSizeOnChatDismiss) - if !channelDataSource.hasLoadedAllNextMessages { - channelDataSource.loadFirstPage { _ in } - } } } } From 0e55d6085d1fd346044fba0b0f0543d9810e1ecb Mon Sep 17 00:00:00 2001 From: Nuno Vieira Date: Thu, 13 Nov 2025 17:33:14 +0000 Subject: [PATCH 3/3] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c270ff3d..a7bb67d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Expose `FilePickerView.init(fileURLs:)` [#1049](https://github.com/GetStream/stream-chat-swiftui/pull/1049) - Add `MessageComposerViewModel.updateAddedAssets()` [#1049](https://github.com/GetStream/stream-chat-swiftui/pull/1049) +### 🐞 Fixed +- Fix `Throttler` crash in `ChatChannelViewModel.handleMessageAppear()` [#1050](https://github.com/GetStream/stream-chat-swiftui/pull/1050) +- Remove unnecessary channel query call when leaving the channel view in a mid-page [#1050](https://github.com/GetStream/stream-chat-swiftui/pull/1050) + # [4.92.0](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.92.0) _November 07, 2025_