fix(ios-watch): ack sendMessage delivery openclaw#20054 thanks @mbelinky

This commit is contained in:
mbelinky
2026-02-18 14:32:45 +01:00
parent 5003b7b2dd
commit d9332aa50f
3 changed files with 33 additions and 5 deletions

View File

@@ -6,6 +6,7 @@ Docs: https://docs.openclaw.ai
### Changes
- iOS/Watch: add an Apple Watch companion MVP with watch inbox UI, watch notification relay handling, and gateway command surfaces for watch status/send flows. (#20054) Thanks @mbelinky.
- Gateway/CLI: add paired-device hygiene flows with `device.pair.remove`, plus `openclaw devices remove` and guarded `openclaw devices clear --yes [--pending]` commands for removing paired entries and optionally rejecting pending requests. (#20057) Thanks @mbelinky.
### Fixes

View File

@@ -92,13 +92,15 @@ final class WatchMessagingService: NSObject, WatchMessagingServicing, @unchecked
]
if snapshot.reachable {
session.sendMessage(payload, replyHandler: nil) { error in
do {
try await self.sendReachableMessage(payload, with: session)
return WatchNotificationSendResult(
deliveredImmediately: true,
queuedForDelivery: false,
transport: "sendMessage")
} catch {
Self.logger.error("watch sendMessage failed: \(error.localizedDescription, privacy: .public)")
}
return WatchNotificationSendResult(
deliveredImmediately: true,
queuedForDelivery: false,
transport: "sendMessage")
}
_ = session.transferUserInfo(payload)
@@ -108,6 +110,16 @@ final class WatchMessagingService: NSObject, WatchMessagingServicing, @unchecked
transport: "transferUserInfo")
}
private func sendReachableMessage(_ payload: [String: Any], with session: WCSession) async throws {
try await withCheckedThrowingContinuation { continuation in
session.sendMessage(payload, replyHandler: { _ in
continuation.resume()
}, errorHandler: { error in
continuation.resume(throwing: error)
})
}
}
private func ensureActivated() async {
guard let session = self.session else { return }
if session.activationState == .activated { return }

View File

@@ -61,6 +61,21 @@ extension WatchConnectivityReceiver: WCSessionDelegate {
}
}
func session(
_: WCSession,
didReceiveMessage message: [String: Any],
replyHandler: @escaping ([String: Any]) -> Void)
{
guard let incoming = Self.parseNotificationPayload(message) else {
replyHandler(["ok": false])
return
}
Task { @MainActor in
self.store.consume(message: incoming, transport: "sendMessage")
replyHandler(["ok": true])
}
}
func session(_: WCSession, didReceiveUserInfo userInfo: [String: Any]) {
guard let incoming = Self.parseNotificationPayload(userInfo) else { return }
Task { @MainActor in