Update Helpers, Services
Summary: - Sources: Helpers, Services - Added symbols: func maxAutoSyncSize, func syncRegisteredKeysIfNeeded, func syncSnapshot Stats: - 2 files changed, 90 insertions(+), 2 deletions(-)
This commit is contained in:
parent
c2b17a4b7f
commit
358e7a0ffc
@ -17,6 +17,11 @@ actor SyncHelper {
|
||||
public func updateConfiguration(_ configuration: SyncConfiguration) {
|
||||
self.configuration = configuration
|
||||
}
|
||||
|
||||
/// Exposes the current max auto-sync size for filtering outbound payloads.
|
||||
public func maxAutoSyncSize() -> Int {
|
||||
configuration.maxAutoSyncSize
|
||||
}
|
||||
|
||||
// MARK: - Public Interface
|
||||
|
||||
@ -68,10 +73,15 @@ actor SyncHelper {
|
||||
guard WCSession.isSupported() else { return false }
|
||||
|
||||
let session = WCSession.default
|
||||
guard session.activationState == .activated else { return false }
|
||||
guard session.activationState == .activated else {
|
||||
Logger.debug("<<< [SYNC] WCSession not activated")
|
||||
return false
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
return session.isPaired && session.isWatchAppInstalled
|
||||
let isAvailable = session.isPaired && session.isWatchAppInstalled
|
||||
Logger.debug("<<< [SYNC] WCSession status paired=\(session.isPaired) installed=\(session.isWatchAppInstalled) reachable=\(session.isReachable)")
|
||||
return isAvailable
|
||||
#else
|
||||
return true
|
||||
#endif
|
||||
@ -100,7 +110,10 @@ actor SyncHelper {
|
||||
guard session.isPaired, session.isWatchAppInstalled else { return }
|
||||
#endif
|
||||
|
||||
Logger.info(">>> [SYNC] Sending application context for key: \(keyName) (\(data.count) bytes)")
|
||||
try session.updateApplicationContext([keyName: data])
|
||||
let contextKeys = session.applicationContext.keys.sorted().joined(separator: ", ")
|
||||
Logger.info("<<< [SYNC] Application context updated for key: \(keyName). Keys now: [\(contextKeys)]")
|
||||
}
|
||||
|
||||
private func setupSession() {
|
||||
|
||||
@ -553,6 +553,81 @@ public actor StorageRouter: StorageProviding {
|
||||
)
|
||||
}
|
||||
|
||||
/// Attempts to sync any registered keys that already have stored values.
|
||||
/// This is useful for bootstrapping watch data after app launch or reconnection.
|
||||
public func syncRegisteredKeysIfNeeded() async {
|
||||
let isAvailable = await sync.isSyncAvailable()
|
||||
guard isAvailable else {
|
||||
Logger.debug("<<< [SYNC] Skipping bootstrap sync: WatchConnectivity unavailable")
|
||||
return
|
||||
}
|
||||
|
||||
Logger.debug(">>> [SYNC] Starting bootstrap sync for registered keys")
|
||||
for entry in registeredKeys.values {
|
||||
let descriptor = entry.descriptor
|
||||
guard descriptor.availability == .all || descriptor.availability == .phoneWithWatchSync else {
|
||||
Logger.debug("<<< [SYNC] Skipping key \(descriptor.name): availability=\(descriptor.availability)")
|
||||
continue
|
||||
}
|
||||
guard descriptor.syncPolicy != .never else {
|
||||
Logger.debug("<<< [SYNC] Skipping key \(descriptor.name): syncPolicy=\(descriptor.syncPolicy)")
|
||||
continue
|
||||
}
|
||||
|
||||
do {
|
||||
guard let storedData = try await retrieve(for: descriptor) else {
|
||||
Logger.debug("<<< [SYNC] No stored data for key \(descriptor.name)")
|
||||
continue
|
||||
}
|
||||
try await sync.syncIfNeeded(
|
||||
data: storedData,
|
||||
keyName: descriptor.name,
|
||||
availability: descriptor.availability,
|
||||
syncPolicy: descriptor.syncPolicy
|
||||
)
|
||||
Logger.debug("<<< [SYNC] Bootstrapped context for key: \(descriptor.name) (\(storedData.count) bytes)")
|
||||
} catch {
|
||||
Logger.error("Failed to bootstrap sync for key: \(descriptor.name)", error: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a snapshot of syncable key data for immediate watch requests.
|
||||
public func syncSnapshot() async -> [String: Data] {
|
||||
let isAvailable = await sync.isSyncAvailable()
|
||||
guard isAvailable else {
|
||||
Logger.debug("<<< [SYNC] Skipping snapshot: WatchConnectivity unavailable")
|
||||
return [:]
|
||||
}
|
||||
|
||||
let maxAutoSyncSize = await sync.maxAutoSyncSize()
|
||||
var payload: [String: Data] = [:]
|
||||
|
||||
for entry in registeredKeys.values {
|
||||
let descriptor = entry.descriptor
|
||||
guard descriptor.availability == .all || descriptor.availability == .phoneWithWatchSync else {
|
||||
continue
|
||||
}
|
||||
guard descriptor.syncPolicy != .never else { continue }
|
||||
|
||||
do {
|
||||
guard let storedData = try await retrieve(for: descriptor) else { continue }
|
||||
|
||||
if descriptor.syncPolicy == .automaticSmall, storedData.count > maxAutoSyncSize {
|
||||
Logger.debug("<<< [SYNC] Snapshot skip \(descriptor.name): size exceeds maxAutoSyncSize")
|
||||
continue
|
||||
}
|
||||
|
||||
payload[descriptor.name] = storedData
|
||||
} catch {
|
||||
Logger.error("Failed to build sync snapshot for key: \(descriptor.name)", error: error)
|
||||
}
|
||||
}
|
||||
|
||||
Logger.debug("<<< [SYNC] Snapshot built with \(payload.count) keys")
|
||||
return payload
|
||||
}
|
||||
|
||||
// MARK: - Internal Sync Handling
|
||||
|
||||
/// Internal method to update storage from received sync data.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user