Restore smart settings and sync watch favourites
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
import Foundation
|
||||
import WatchConnectivity
|
||||
|
||||
extension Notification.Name {
|
||||
static let fuelBoardWatchRefreshRequested = Notification.Name("FuelBoardWatchRefreshRequested")
|
||||
}
|
||||
|
||||
@MainActor
|
||||
final class WatchSyncManager: NSObject, WCSessionDelegate {
|
||||
static let shared = WatchSyncManager()
|
||||
|
||||
private var pendingSnapshotPush = false
|
||||
|
||||
private override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func activate() {
|
||||
guard WCSession.isSupported() else { return }
|
||||
pendingSnapshotPush = true
|
||||
let session = WCSession.default
|
||||
if session.delegate !== self {
|
||||
session.delegate = self
|
||||
}
|
||||
session.activate()
|
||||
}
|
||||
|
||||
func pushSnapshot() {
|
||||
guard WCSession.isSupported() else { return }
|
||||
let session = WCSession.default
|
||||
guard session.activationState == .activated else {
|
||||
pendingSnapshotPush = true
|
||||
return
|
||||
}
|
||||
do {
|
||||
try session.updateApplicationContext(snapshotContext())
|
||||
pendingSnapshotPush = false
|
||||
} catch {
|
||||
print("WATCH-SYNC push failed: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
private func snapshotContext() -> [String: Any] {
|
||||
var context: [String: Any] = [:]
|
||||
|
||||
if let favourites = try? JSONEncoder().encode(FuelStore.loadFavourites()) {
|
||||
context[FuelStore.favouritesKey] = favourites
|
||||
}
|
||||
|
||||
context[FuelStore.fuelKey] = FuelStore.loadSelectedFuel().rawValue
|
||||
context[FuelStore.distanceUnitKey] = FuelStore.loadDistanceUnit().rawValue
|
||||
context[FuelStore.priceDisplayStyleKey] = FuelStore.loadPriceDisplayStyle().rawValue
|
||||
|
||||
if let lastRefresh = FuelStore.loadLastRefresh() {
|
||||
context[FuelStore.lastRefreshKey] = String(lastRefresh.timeIntervalSince1970)
|
||||
}
|
||||
|
||||
if let handled = FuelStore.loadWatchRefreshHandled() {
|
||||
context[FuelStore.watchRefreshHandledKey] = String(handled.timeIntervalSince1970)
|
||||
}
|
||||
|
||||
if let location = FuelStore.loadLocationWithDate() {
|
||||
context[FuelStore.locationKey] = "\(location.coordinate.lat),\(location.coordinate.lng),\(location.date.timeIntervalSince1970)"
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
nonisolated func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: (any Error)?) {
|
||||
if let error {
|
||||
print("WATCH-SYNC activation failed: \(error.localizedDescription)")
|
||||
return
|
||||
}
|
||||
Task { @MainActor in
|
||||
if activationState == .activated, self.pendingSnapshotPush {
|
||||
self.pushSnapshot()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nonisolated func sessionDidBecomeInactive(_ session: WCSession) {}
|
||||
|
||||
nonisolated func sessionDidDeactivate(_ session: WCSession) {
|
||||
Task { @MainActor in
|
||||
WCSession.default.activate()
|
||||
}
|
||||
}
|
||||
|
||||
nonisolated func session(_ session: WCSession, didReceiveUserInfo userInfo: [String : Any] = [:]) {
|
||||
handleIncomingRefreshRequest(userInfo)
|
||||
}
|
||||
|
||||
nonisolated func session(_ session: WCSession, didReceiveMessage message: [String : Any]) {
|
||||
handleIncomingRefreshRequest(message)
|
||||
}
|
||||
|
||||
private nonisolated func handleIncomingRefreshRequest(_ payload: [String: Any]) {
|
||||
guard let raw = payload[FuelStore.watchRefreshRequestKey] as? String,
|
||||
let timestamp = TimeInterval(raw) else { return }
|
||||
let date = Date(timeIntervalSince1970: timestamp)
|
||||
Task { @MainActor in
|
||||
FuelStore.requestWatchRefresh(date)
|
||||
NotificationCenter.default.post(name: .fuelBoardWatchRefreshRequested, object: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user