listless

A simple list app for Apple platforms
Log | Files | Refs | README | LICENSE

KeyValueSyncBridge.swift (2040B)


      1 import Foundation
      2 
      3 final class KeyValueSyncBridge {
      4     private let keys: Set<String>
      5     private var isSyncing = false
      6 
      7     init(keys: Set<String>) {
      8         self.keys = keys
      9     }
     10 
     11     func start() {
     12         let cloud = NSUbiquitousKeyValueStore.default
     13         cloud.synchronize()
     14 
     15         for key in keys {
     16             if let cloudValue = cloud.object(forKey: key) {
     17                 isSyncing = true
     18                 UserDefaults.standard.set(cloudValue, forKey: key)
     19                 isSyncing = false
     20             }
     21         }
     22 
     23         NotificationCenter.default.addObserver(
     24             self,
     25             selector: #selector(cloudDidChange),
     26             name: NSUbiquitousKeyValueStore.didChangeExternallyNotification,
     27             object: cloud
     28         )
     29 
     30         NotificationCenter.default.addObserver(
     31             self,
     32             selector: #selector(defaultsDidChange),
     33             name: UserDefaults.didChangeNotification,
     34             object: nil
     35         )
     36     }
     37 
     38     @objc private func cloudDidChange(_ notification: Notification) {
     39         guard !isSyncing else { return }
     40         guard let changedKeys = notification.userInfo?[NSUbiquitousKeyValueStoreChangedKeysKey] as? [String] else {
     41             return
     42         }
     43         let cloud = NSUbiquitousKeyValueStore.default
     44         isSyncing = true
     45         for key in changedKeys where keys.contains(key) {
     46             UserDefaults.standard.set(cloud.object(forKey: key), forKey: key)
     47         }
     48         isSyncing = false
     49     }
     50 
     51     @objc private func defaultsDidChange(_ notification: Notification) {
     52         guard !isSyncing else { return }
     53         let defaults = UserDefaults.standard
     54         let cloud = NSUbiquitousKeyValueStore.default
     55         isSyncing = true
     56         for key in keys {
     57             let localValue = defaults.object(forKey: key) as? NSObject
     58             let cloudValue = cloud.object(forKey: key) as? NSObject
     59             if localValue != cloudValue {
     60                 cloud.set(localValue, forKey: key)
     61             }
     62         }
     63         isSyncing = false
     64     }
     65 }