fix(dev): pending inspector stable times and refreshPending without nested busy

Expose wall-clock fire targets from the iOS NotificationInspector
(scheduled_time userInfo and predictive_<epochMs> ids) so the debug
panel is not misleading when nextTriggerDate resamples for interval
triggers. Extend TS types and show the scheduled target in the UI,
with a note when iOS nextTriggerDate diverges.

Make refreshPending a plain fetch so mock refresh, wakeup ping, flood
test, and clear notifications can refresh the pending list while an
outer withBusy guard is already active.
This commit is contained in:
Jose Olarte III
2026-05-11 13:50:52 +08:00
parent 48637ae9a8
commit 5a40075ab1
4 changed files with 77 additions and 11 deletions

View File

@@ -16,6 +16,29 @@ public class NotificationInspectorPlugin: CAPPlugin, CAPBridgedPlugin {
]
}
/// Stable wall-clock target: plugin `userInfo["scheduled_time"]`, or epoch ms in `predictive_<ms>` identifiers.
/// (Apple documents `UNTimeIntervalNotificationTrigger.nextTriggerDate()` as resampling ~now+interval when queried.)
private func wallClockMillis(from request: UNNotificationRequest) -> (ms: Int64, source: String)? {
let info = request.content.userInfo
if let v = info["scheduled_time"] as? Int64 {
return (v, "userInfo.scheduled_time")
}
if let n = info["scheduled_time"] as? NSNumber {
return (n.int64Value, "userInfo.scheduled_time")
}
if let i = info["scheduled_time"] as? Int {
return (Int64(i), "userInfo.scheduled_time")
}
let prefix = "predictive_"
if request.identifier.hasPrefix(prefix) {
let suffix = String(request.identifier.dropFirst(prefix.count))
if let ms = Int64(suffix) {
return (ms, "identifier(predictive_)")
}
}
return nil
}
@objc public func getPendingNotifications(_ call: CAPPluginCall) {
UNUserNotificationCenter.current().getPendingNotificationRequests { requests in
let pending: [[String: Any]] = requests.map { req in
@@ -43,6 +66,13 @@ public class NotificationInspectorPlugin: CAPPlugin, CAPBridgedPlugin {
]
obj["nextTriggerDate"] = nextTriggerMs ?? NSNull()
obj["triggerType"] = triggerType ?? NSNull()
if let wall = self.wallClockMillis(from: req) {
obj["wallClockMillis"] = NSNumber(value: wall.ms)
obj["wallClockSource"] = wall.source
} else {
obj["wallClockMillis"] = NSNull()
obj["wallClockSource"] = NSNull()
}
return obj
}