From 8cda2c59bbeec6361b2ce808b8870fea743dba96 Mon Sep 17 00:00:00 2001 From: Bahadir Oncel Date: Mon, 2 Aug 2021 16:03:02 +0200 Subject: [PATCH] Fix CoreData misuse when creating Direct Messaging channels --- CHANGELOG.md | 1 + .../ChannelController/ChannelController.swift | 8 +++++--- .../ChannelController/ChannelController_Tests.swift | 13 +++++++++++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb4f2e9a606..602e3e8a082 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fix compilation for Xcode 13 beta 3 where SDK could not compile because of unvailability of `UIApplication.shared` [#1333](https://github.com/GetStream/stream-chat-swift/pull/1333) - Fix member removed from a Channel is still present is MemberListController.members [#1323](https://github.com/GetStream/stream-chat-swift/issues/1323) - Fix composer input field height for long text [#1335](https://github.com/GetStream/stream-chat-swift/issues/1335) +- Fix creating direct messaging channels creates CoreData misuse [#1337](https://github.com/GetStream/stream-chat-swift/issues/1337) ### 🔄 Changed - `ContainerStackView` doesn't `assert` when trying to remove a subview, these operations are now no-op [#1328](https://github.com/GetStream/stream-chat-swift/issues/1328) diff --git a/Sources/StreamChat/Controllers/ChannelController/ChannelController.swift b/Sources/StreamChat/Controllers/ChannelController/ChannelController.swift index 896061c3d4a..4cdbff0c38b 100644 --- a/Sources/StreamChat/Controllers/ChannelController/ChannelController.swift +++ b/Sources/StreamChat/Controllers/ChannelController/ChannelController.swift @@ -309,15 +309,17 @@ public class _ChatChannelController: DataController, _messagesObserver.computeValue = { [unowned self] in guard let cid = self.cid else { return nil } let sortAscending = self.listOrdering == .topToBottom ? false : true - let deletedMessageVisibility = self.client.databaseContainer.viewContext - .deletedMessagesVisibility ?? .visibleForCurrentUser + var deletedMessageVisibility: ChatClientConfig.DeletedMessageVisibility? + self.client.databaseContainer.viewContext.performAndWait { + deletedMessageVisibility = self.client.databaseContainer.viewContext.deletedMessagesVisibility + } let observer = ListDatabaseObserver( context: self.client.databaseContainer.viewContext, fetchRequest: MessageDTO.messagesFetchRequest( for: cid, sortAscending: sortAscending, - deletedMessagesVisibility: deletedMessageVisibility + deletedMessagesVisibility: deletedMessageVisibility ?? .visibleForCurrentUser ), itemCreator: { $0.asModel() as _ChatMessage } ) diff --git a/Sources/StreamChat/Controllers/ChannelController/ChannelController_Tests.swift b/Sources/StreamChat/Controllers/ChannelController/ChannelController_Tests.swift index 4d71118209a..15f0387d138 100644 --- a/Sources/StreamChat/Controllers/ChannelController/ChannelController_Tests.swift +++ b/Sources/StreamChat/Controllers/ChannelController/ChannelController_Tests.swift @@ -378,8 +378,17 @@ class ChannelController_Tests: StressTestCase { try client.databaseContainer.writeSynchronously { try $0.saveChannel(payload: payload, query: nil) } - env.channelUpdater?.update_channelCreatedCallback?(channelId) - env.channelUpdater?.update_completion?(.success(dummyPayload(with: .unique))) + + // We call these callbacks on a queue other than main queue + // to simulate the actual scenario where callbacks will be called + // from NSURLSession-delegate (serial) queue + let _: Bool = try waitFor { completion in + DispatchQueue.global().async { + self.env.channelUpdater?.update_channelCreatedCallback?(self.channelId) + self.env.channelUpdater?.update_completion?(.success(self.dummyPayload(with: .unique))) + completion(true) + } + } XCTAssertEqual(controller.channel?.cid, channelId) XCTAssertEqual(controller.messages.count, payload.messages.count)