Summary: - Sources: Services - Added symbols: actor EncryptionHelper, actor FileStorageHelper, actor KeychainHelper, func registerKeyMaterialProvider, actor SyncHelper, actor UserDefaultsHelper - Removed symbols: actor EncryptionHelper, actor FileStorageHelper, actor KeychainHelper, actor SyncHelper, actor UserDefaultsHelper Stats: - 6 files changed, 15 insertions(+), 5 deletions(-)
112 lines
3.4 KiB
Swift
112 lines
3.4 KiB
Swift
import Foundation
|
|
#if os(iOS) || os(watchOS)
|
|
import WatchConnectivity
|
|
#endif
|
|
|
|
/// Actor that handles WatchConnectivity sync operations.
|
|
/// Manages data synchronization between iPhone and Apple Watch.
|
|
actor SyncHelper {
|
|
|
|
public static let shared = SyncHelper()
|
|
|
|
/// Maximum data size for automatic sync (100KB).
|
|
public static let maxAutoSyncSize = 100_000
|
|
|
|
private init() {}
|
|
|
|
// MARK: - Public Interface
|
|
|
|
/// Syncs data to the paired device if appropriate.
|
|
/// - Parameters:
|
|
/// - data: The data to sync.
|
|
/// - keyName: The key name for the application context.
|
|
/// - availability: The platform availability setting.
|
|
/// - syncPolicy: The sync policy setting.
|
|
/// - Throws: `StorageError.dataTooLargeForSync` if data exceeds size limit for automatic sync.
|
|
public func syncIfNeeded(
|
|
data: Data,
|
|
keyName: String,
|
|
availability: PlatformAvailability,
|
|
syncPolicy: SyncPolicy
|
|
) throws {
|
|
#if os(iOS) || os(watchOS)
|
|
// Only sync for appropriate availability settings
|
|
guard availability == .all || availability == .phoneWithWatchSync else {
|
|
return
|
|
}
|
|
|
|
switch syncPolicy {
|
|
case .never:
|
|
return
|
|
|
|
case .automaticSmall:
|
|
guard data.count <= Self.maxAutoSyncSize else {
|
|
throw StorageError.dataTooLargeForSync
|
|
}
|
|
try performSync(data: data, keyName: keyName)
|
|
|
|
case .manual:
|
|
try performSync(data: data, keyName: keyName)
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/// Manually triggers a sync for the given data.
|
|
/// - Parameters:
|
|
/// - data: The data to sync.
|
|
/// - keyName: The key name for the application context.
|
|
/// - Throws: Various errors if sync fails.
|
|
public func manualSync(data: Data, keyName: String) throws {
|
|
#if os(iOS) || os(watchOS)
|
|
try performSync(data: data, keyName: keyName)
|
|
#endif
|
|
}
|
|
|
|
/// Checks if sync is available.
|
|
/// - Returns: True if WatchConnectivity is supported and active.
|
|
public func isSyncAvailable() -> Bool {
|
|
#if os(iOS) || os(watchOS)
|
|
guard WCSession.isSupported() else { return false }
|
|
|
|
let session = WCSession.default
|
|
guard session.activationState == .activated else { return false }
|
|
|
|
#if os(iOS)
|
|
return session.isPaired && session.isWatchAppInstalled
|
|
#else
|
|
return true
|
|
#endif
|
|
#else
|
|
return false
|
|
#endif
|
|
}
|
|
|
|
/// Gets the current application context.
|
|
/// - Returns: The current application context dictionary.
|
|
public func currentContext() -> [String: Any] {
|
|
#if os(iOS) || os(watchOS)
|
|
guard WCSession.isSupported() else { return [:] }
|
|
return WCSession.default.applicationContext
|
|
#else
|
|
return [:]
|
|
#endif
|
|
}
|
|
|
|
// MARK: - Private Helpers
|
|
|
|
#if os(iOS) || os(watchOS)
|
|
private func performSync(data: Data, keyName: String) throws {
|
|
guard WCSession.isSupported() else { return }
|
|
|
|
let session = WCSession.default
|
|
guard session.activationState == .activated else { return }
|
|
|
|
#if os(iOS)
|
|
guard session.isPaired, session.isWatchAppInstalled else { return }
|
|
#endif
|
|
|
|
try session.updateApplicationContext([keyName: data])
|
|
}
|
|
#endif
|
|
}
|