diff --git a/FuelBoard/ProximityMonitor.swift b/FuelBoard/ProximityMonitor.swift
index ee00a1d..5bbd82e 100644
--- a/FuelBoard/ProximityMonitor.swift
+++ b/FuelBoard/ProximityMonitor.swift
@@ -209,13 +209,13 @@ final class ProximityMonitor: NSObject, ObservableObject, @preconcurrency CLLoca
]
let identifier = UUID().uuidString
- // Deliver the notification IMMEDIATELY — the alert must never wait on
- // the map. If the snapshot later succeeds, the same identifier is used
- // to replace the delivered notification with the map attached.
+ // Render the map FIRST, then deliver ONE notification with the map
+ // attached. (Earlier, delivering immediately and "replacing" via a
+ // second add() showed up as two notifications in LiveContainer — the
+ // replace-in-place contract isn't honoured there.) A timeout
+ // guarantees the alert still fires, without the map, if the snapshot
+ // hangs.
mapStatus?("map: preparing…")
- UNUserNotificationCenter.current().add(
- UNNotificationRequest(identifier: identifier, content: content, trigger: nil)
- )
let options = MKMapSnapshotter.Options()
options.region = MKCoordinateRegion(
@@ -226,24 +226,28 @@ final class ProximityMonitor: NSObject, ObservableObject, @preconcurrency CLLoca
options.mapType = .standard
let snapshotter = MKMapSnapshotter(options: options)
- // Timeout so a hung snapshot can't leave the result line stuck on
- // "preparing" forever.
var finished = false
+ let deliver: (String) -> Void = { status in
+ guard !finished else { return }
+ finished = true
+ mapStatus?(status)
+ UNUserNotificationCenter.current().add(
+ UNNotificationRequest(identifier: identifier, content: content, trigger: nil)
+ )
+ }
+
+ // Timeout so a hung snapshot can't leave the alert undelivered (and
+ // the result line stuck on "preparing") forever.
let timeout = DispatchWorkItem {
Task { @MainActor in
- guard !finished else { return }
- finished = true
- mapStatus?("map: timed out")
+ deliver("map: timed out — no image")
}
}
- DispatchQueue.main.asyncAfter(deadline: .now() + 8, execute: timeout)
+ DispatchQueue.main.asyncAfter(deadline: .now() + 10, execute: timeout)
snapshotter.start { [content] snapshot, error in
timeout.cancel()
Task { @MainActor in
- guard !finished else { return }
- finished = true
- let finalContent = content
var status = "map: no image"
if let snapshot, error == nil,
let image = Self.mapImage(snapshot: snapshot, station: station) {
@@ -251,18 +255,13 @@ final class ProximityMonitor: NSObject, ObservableObject, @preconcurrency CLLoca
.appendingPathComponent("alert-map-\(UUID().uuidString).png")
if let data = image.pngData(), (try? data.write(to: url)) != nil,
let attachment = try? UNNotificationAttachment(identifier: "map", url: url, options: nil) {
- finalContent.attachments = [attachment]
+ content.attachments = [attachment]
status = "map: attached"
}
} else if let error {
status = "map: snapshot failed (\(error.localizedDescription))"
}
- mapStatus?(status)
- // Replace the delivered notification (same identifier) so the
- // map appears in place.
- UNUserNotificationCenter.current().add(
- UNNotificationRequest(identifier: identifier, content: finalContent, trigger: nil)
- )
+ deliver(status)
}
}
}
diff --git a/build-tests/Logs/Launch/LogStoreManifest.plist b/build-tests/Logs/Launch/LogStoreManifest.plist
new file mode 100644
index 0000000..236d5e2
--- /dev/null
+++ b/build-tests/Logs/Launch/LogStoreManifest.plist
@@ -0,0 +1,10 @@
+
+
+
+
+ logFormatVersion
+ 12
+ logs
+
+
+
diff --git a/build-tests/Logs/Localization/LogStoreManifest.plist b/build-tests/Logs/Localization/LogStoreManifest.plist
new file mode 100644
index 0000000..236d5e2
--- /dev/null
+++ b/build-tests/Logs/Localization/LogStoreManifest.plist
@@ -0,0 +1,10 @@
+
+
+
+
+ logFormatVersion
+ 12
+ logs
+
+
+
diff --git a/build-tests/Logs/Package/LogStoreManifest.plist b/build-tests/Logs/Package/LogStoreManifest.plist
new file mode 100644
index 0000000..236d5e2
--- /dev/null
+++ b/build-tests/Logs/Package/LogStoreManifest.plist
@@ -0,0 +1,10 @@
+
+
+
+
+ logFormatVersion
+ 12
+ logs
+
+
+
diff --git a/build-tests/Logs/Test/LogStoreManifest.plist b/build-tests/Logs/Test/LogStoreManifest.plist
new file mode 100644
index 0000000..236d5e2
--- /dev/null
+++ b/build-tests/Logs/Test/LogStoreManifest.plist
@@ -0,0 +1,10 @@
+
+
+
+
+ logFormatVersion
+ 12
+ logs
+
+
+