Harden Apple Watch snapshot synchronization

This commit is contained in:
2026-08-17 18:06:09 +02:00
parent 5c88d3ace0
commit 2a59803b6c
8 changed files with 372 additions and 64 deletions

View File

@@ -46,6 +46,7 @@ private final class WatchSnapshotCoordinator: NSObject, WCSessionDelegate {
Notification.Name.ironStorageWatchSnapshotDidChange,
.ironStorageLocalStoreDidChange,
.ironStorageAuthenticationDidChange,
UIApplication.didBecomeActiveNotification,
] {
NotificationCenter.default.addObserver(
self,
@@ -103,21 +104,7 @@ private final class WatchSnapshotCoordinator: NSObject, WCSessionDelegate {
Self.snapshotKey: snapshot,
Self.deliveredReceiptKey: Data(transfer.deliveredReceipt),
]
do {
try session.updateApplicationContext(payload)
if session.isReachable {
session.sendMessage(payload, replyHandler: nil) { _ in
session.transferUserInfo(payload)
}
} else {
session.transferUserInfo(payload)
}
} catch {
_ = try? authentication.failWatchSnapshot(
revision: transfer.revision,
detail: "The latest Apple Watch snapshot could not be queued."
)
}
publish(payload, through: session)
notifyStatusChanged()
case .failure:
// A locked GPG key leaves the previous replacement pending. Authentication
@@ -127,6 +114,18 @@ private final class WatchSnapshotCoordinator: NSObject, WCSessionDelegate {
}
}
private func publish(_ payload: [String: Any], through session: WCSession) {
for transfer in session.outstandingUserInfoTransfers
where transfer.userInfo[Self.snapshotKey] != nil {
transfer.cancel()
}
try? session.updateApplicationContext(payload)
session.transferUserInfo(payload)
if session.isReachable {
session.sendMessage(payload, replyHandler: nil) { _ in }
}
}
private func recordUnavailable(unpaired: Bool, detail: String) {
guard let authentication else { return }
_ = try? authentication.setWatchSnapshotUnavailable(unpaired: unpaired, detail: detail)