Implement WatchConnectivity relay bridge
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
#if os(watchOS)
|
||||
import Foundation
|
||||
import RemoteCore
|
||||
import WatchBridgeCommon
|
||||
import WatchConnectivity
|
||||
|
||||
@MainActor
|
||||
private final class WatchWCSessionSending: RelaySessionSending {
|
||||
private let session: WCSession
|
||||
init(session: WCSession) { self.session = session }
|
||||
var activationState: RelayActivationState {
|
||||
switch session.activationState {
|
||||
case .notActivated: return .notActivated
|
||||
case .inactive: return .inactive
|
||||
case .activated: return .activated
|
||||
@unknown default: return .inactive
|
||||
}
|
||||
}
|
||||
var isReachable: Bool { session.isReachable }
|
||||
func activate() { session.activate() }
|
||||
func sendMessage(_ message: [String: Any],
|
||||
replyHandler: @escaping ([String: Any]) -> Void,
|
||||
errorHandler: @escaping (Error) -> Void) {
|
||||
session.sendMessage(message, replyHandler: replyHandler, errorHandler: errorHandler)
|
||||
}
|
||||
func updateApplicationContext(_ context: [String: Any]) throws {
|
||||
try session.updateApplicationContext(context)
|
||||
}
|
||||
}
|
||||
|
||||
/// Separate watchOS delegate. The app remains foreground/active for gesture
|
||||
/// use; this delegate does not add a background mode or deferred command queue.
|
||||
@MainActor
|
||||
public final class WatchWCSessionDelegate: NSObject, WCSessionDelegate {
|
||||
public let bridge: WatchRelayBridge
|
||||
|
||||
public init(session: WCSession = .default) {
|
||||
bridge = WatchRelayBridge(session: WatchWCSessionSending(session: session))
|
||||
super.init()
|
||||
session.delegate = self
|
||||
bridge.activate()
|
||||
}
|
||||
|
||||
nonisolated public func session(_ session: WCSession,
|
||||
activationDidCompleteWith activationState: WCSessionActivationState,
|
||||
error: Error?) {
|
||||
Task { @MainActor [weak self] in
|
||||
guard let self else { return }
|
||||
if case .inactive = self.bridge.state { } else { self.bridge.didDeactivate() }
|
||||
self.bridge.activationDidComplete(error: error)
|
||||
}
|
||||
}
|
||||
|
||||
nonisolated public func sessionReachabilityDidChange(_ session: WCSession) {
|
||||
Task { @MainActor [weak self] in self?.bridge.reachabilityDidChange() }
|
||||
}
|
||||
|
||||
nonisolated public func session(_ session: WCSession,
|
||||
didReceiveMessage message: [String: Any],
|
||||
replyHandler: @escaping ([String: Any]) -> Void) {
|
||||
// The watch is the request sender in v1; never execute a phone reply
|
||||
// as a request. Complete unexpected inbound traffic exactly once.
|
||||
RelayReplyOnce(replyHandler).reply(
|
||||
relayErrorReply(RelayFailure(code: .malformedRequest)))
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user