Skip to content
This repository has been archived by the owner on Oct 1, 2024. It is now read-only.

Commit

Permalink
Workaround SwiftUI Windows never canceling tasks, Apple earning that …
Browse files Browse the repository at this point in the history
…Core Technology Fee
  • Loading branch information
josh committed Apr 16, 2024
1 parent 3b355b7 commit 49020e9
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
25 changes: 25 additions & 0 deletions Aware/macOS/LogWindow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,20 @@ private nonisolated(unsafe) let logger = Logger(

struct LogWindow: Scene {
@State private var logs = LogCollection()
@State private var nsWindow: NSWindow?
@State private var windowIsVisible: Bool = true

var body: some Scene {
Window("Logs", id: "logs") {
LogListView(logs, metadata: .hide(.processName, .pid), reversed: true)
.task {
for await isVisible in windowVisibleUpdates(title: "Logs") {
self.windowIsVisible = isVisible
}
}
.task(id: windowIsVisible) {
guard windowIsVisible else { return }

do {
for try await log in logUpdates() {
if log.library == "Aware" || log.library == "SwiftUI" {
Expand All @@ -31,9 +40,25 @@ struct LogWindow: Scene {
} catch {
logger.error("Failed to load logs: \(error, privacy: .public)")
}

print("isCanceled", Task.isCancelled)
}
}
}
}

@MainActor
func windowVisibleUpdates(title: String) -> AsyncCompactMapSequence<MergedNotifications, Bool> {
return NotificationCenter.default.mergeNotifications(named: [
NSWindow.didBecomeKeyNotification,
NSWindow.willCloseNotification,
]).compactMap { @MainActor notification in
if let window = notification.object as? NSWindow, window.title == title {
return window.isVisible
} else {
return nil
}
}
}

#endif
7 changes: 5 additions & 2 deletions Packages/ConsoleKit/Sources/ConsoleKit/LogStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@ public func logUpdates(

while !Task.isCancelled {
let position = store.position(date: positionDate)
let entries = try store.getEntries(at: position)
let entries = try store.getEntries(
at: position,
matching: NSPredicate(format: "date > %@", argumentArray: [positionDate])
)
var lastEntry: OSLogEntry?

for entry in entries {
guard entry.date > positionDate else { continue }
assert(entry.date > positionDate, "expcted predicate to filter entries by date")
if let entryLog = entry as? OSLogEntryLog {
let log = Log(entryLog)
assert(log.processIdentifier == currentProcessIdentifier)
Expand Down

0 comments on commit 49020e9

Please sign in to comment.