diff --git a/DuckDuckGo/RemoteMessaging/RemoteMessagingClient.swift b/DuckDuckGo/RemoteMessaging/RemoteMessagingClient.swift index ecc73999fc..6e4b10376e 100644 --- a/DuckDuckGo/RemoteMessaging/RemoteMessagingClient.swift +++ b/DuckDuckGo/RemoteMessaging/RemoteMessagingClient.swift @@ -195,7 +195,8 @@ final class RemoteMessagingClient: RemoteMessagingProcessing { isRemoteMessagingDatabaseLoaded = true } - private var isRemoteMessagingDatabaseLoaded = false + // Publicly accessible for use in RemoteMessagingDebugMenu + private(set) var isRemoteMessagingDatabaseLoaded = false private let remoteMessagingStoreProvider: RemoteMessagingStoreProviding private var scheduledRefreshCancellable: AnyCancellable? private var featureFlagCancellable: AnyCancellable? diff --git a/DuckDuckGo/RemoteMessaging/RemoteMessagingDebugMenu.swift b/DuckDuckGo/RemoteMessaging/RemoteMessagingDebugMenu.swift index 6cfb5eff71..1543a87946 100644 --- a/DuckDuckGo/RemoteMessaging/RemoteMessagingDebugMenu.swift +++ b/DuckDuckGo/RemoteMessaging/RemoteMessagingDebugMenu.swift @@ -22,6 +22,36 @@ import AppKitExtensions final class RemoteMessagingDebugMenu: NSMenu { + struct MessageModel: CustomStringConvertible { + let id: String + let shown: String + let status: String + + init(message: RemoteMessageManagedObject) { + self.id = message.id ?? "?" + self.shown = message.shown ? "shown" : "not shown" + self.status = Self.statusString(for: message.status) + } + + var description: String { + "ID: \(id) | \(shown) | \(status)" + } + + /// This should be kept in sync with `RemoteMessageStatus` private enum from BSK + private static func statusString(for status: NSNumber?) -> String { + switch status?.int16Value { + case 0: + return "scheduled" + case 1: + return "dismissed" + case 2: + return "done" + default: + return "unknown" + } + } + } + init() { super.init(title: "") @@ -48,24 +78,32 @@ final class RemoteMessagingDebugMenu: NSMenu { removeItem(at: 3) } - guard NSApplication.runType.requiresEnvironment else { + guard NSApplication.runType.requiresEnvironment, NSApp.delegateTyped.remoteMessagingClient.isRemoteMessagingDatabaseLoaded else { return } let database = NSApp.delegateTyped.remoteMessagingClient.database - let context = database.makeContext(concurrencyType: .mainQueueConcurrencyType) + let context = database.makeContext(concurrencyType: .privateQueueConcurrencyType) let fetchRequest = RemoteMessageManagedObject.fetchRequest() fetchRequest.returnsObjectsAsFaults = false - let messages = (try? context.fetch(fetchRequest)) ?? [] - let headerItem = NSMenuItem(title: "\(messages.count) Message(s) in database:") + var messageModels: [MessageModel] = [] + + context.performAndWait { + let messages = (try? context.fetch(fetchRequest)) ?? [] + for message in messages { + messageModels.append(MessageModel(message: message)) + } + } + + let headerItem = NSMenuItem(title: "\(messageModels.count) Message(s) in database:") headerItem.isEnabled = false addItem(NSMenuItem.separator()) addItem(headerItem) - for message in messages { - let item = NSMenuItem(title: "ID: \(message.id ?? "?") | \(message.shown ? "shown" : "not shown") | \(statusString(for: message.status))") + for message in messageModels { + let item = NSMenuItem(title: message.description) item.isEnabled = false addItem(item) } @@ -81,17 +119,4 @@ final class RemoteMessagingDebugMenu: NSMenu { } } - /// This should be kept in sync with `RemoteMessageStatus` private enum from BSK - private func statusString(for status: NSNumber?) -> String { - switch status?.int16Value { - case 0: - return "scheduled" - case 1: - return "dismissed" - case 2: - return "done" - default: - return "unknown" - } - } }