diff --git a/Rocket.Chat/Controllers/Subscriptions/SubscriptionsList/SubscriptionsViewModel.swift b/Rocket.Chat/Controllers/Subscriptions/SubscriptionsList/SubscriptionsViewModel.swift index f79048fc90..cb5d63bb48 100644 --- a/Rocket.Chat/Controllers/Subscriptions/SubscriptionsList/SubscriptionsViewModel.swift +++ b/Rocket.Chat/Controllers/Subscriptions/SubscriptionsList/SubscriptionsViewModel.swift @@ -72,6 +72,7 @@ class SubscriptionsViewModel { func buildSections() { if let realm = realm, assorter == nil { + // TODO: Make this realm instance in another thread assorter = RealmAssorter(realm: realm) assorter?.didUpdateIndexPaths = didUpdateIndexPaths } diff --git a/Rocket.Chat/Helpers/RealmAssorter.swift b/Rocket.Chat/Helpers/RealmAssorter.swift index 5059ca281c..f9abd4c8ae 100644 --- a/Rocket.Chat/Helpers/RealmAssorter.swift +++ b/Rocket.Chat/Helpers/RealmAssorter.swift @@ -12,6 +12,7 @@ import DifferenceKit typealias IndexPathsChanges = (deletions: [IndexPath], insertions: [IndexPath], modifications: [IndexPath]) let subscriptionUpdatesHandlerQueue = DispatchQueue(label: "chat.rocket.subscription.updates.handler", qos: .background) +let sectionBuildingQueue = DispatchQueue(label: "chat.rocket.section.building", qos: .background) class RealmAssorter { typealias IndexPathsChangesEvent = (StagedChangeset<[ArraySection]>, (_ newData: [ArraySection]) -> Void) -> Void @@ -20,8 +21,30 @@ class RealmAssorter { let name: String var objects: Results - var section: ArraySection { - return ArraySection(model: name, elements: objects.compactMap { $0.unmanaged }) + func buildSection(completion: @escaping (ArraySection) -> Void) { + let objectIds: [String] = objects.compactMap { + return $0.value(forKeyPath: "identifier") as? String + } + + sectionBuildingQueue.async { + guard + let configuration = self.objects.realm?.configuration, + let realm = try? Realm(configuration: configuration) + else { + return + } + + let unmanagedObjects = objectIds.compactMap { + realm.object(ofType: Object.self, forPrimaryKey: $0)?.unmanaged + } + + completion( + ArraySection( + model: self.name, + elements: unmanagedObjects + ) + ) + } } } @@ -62,7 +85,19 @@ class RealmAssorter { self.model?.invalidate() self.model = model.observe { _ in let oldValue = self.sections - let newValue = self.results.map { $0.section } + var newValue: [ArraySection] = [] + let dispatchGroup = DispatchGroup() + + for result in self.results { + dispatchGroup.enter() + + result.buildSection(completion: { (section) in + newValue.append(section) + dispatchGroup.leave() + }) + } + + dispatchGroup.wait() let changes = StagedChangeset(source: oldValue, target: newValue)