UserDefaultsValueGroups.swift 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. // LoopFollow
  2. // UserDefaultsValueGroups.swift
  3. // Created by Jon Fawcett on 2020-06-05.
  4. import Foundation
  5. /// UserDefaultValue groups manager class, providing change observation capabilities (keep clients informed when a change occured in a given group).
  6. class UserDefaultsValueGroups {
  7. class func values(from groupName: String) -> [UserDefaultsAnyValue]? {
  8. return groupNameToValues[groupName]
  9. }
  10. class func add(_ value: UserDefaultsAnyValue, to groupName: String) {
  11. // add to "value-key to groupNames" dictionary
  12. var groupNames = valueKeyToGroupNames[value.key] ?? []
  13. guard !groupNames.contains(groupName) else {
  14. // already added value to this group!
  15. return
  16. }
  17. groupNames.append(groupName)
  18. valueKeyToGroupNames[value.key] = groupNames
  19. // add to "groupName to value" dictionary
  20. var values = groupNameToValues[groupName] ?? []
  21. values.append(value)
  22. groupNameToValues[groupName] = values
  23. }
  24. @discardableResult
  25. class func observeChanges(in groupName: String, using closure: @escaping (UserDefaultsAnyValue, String) -> Void) -> ObservationToken {
  26. let id = UUID()
  27. var observers = groupNameToObservers[groupName] ?? [:]
  28. observers[id] = closure
  29. groupNameToObservers[groupName] = observers
  30. return ObservationToken {
  31. groupNameToObservers[groupName]?.removeValue(forKey: id)
  32. }
  33. }
  34. // called by UserDefaultsValue instances when value changes
  35. class func valueChanged(_ value: UserDefaultsAnyValue) {
  36. valueKeyToGroupNames[value.key]?.forEach { groupName in
  37. notifyValueChanged(value, in: groupName)
  38. }
  39. }
  40. private class func notifyValueChanged(_ value: UserDefaultsAnyValue, in groupName: String) {
  41. groupNameToObservers[groupName]?.values.forEach { closure in
  42. closure(value, groupName)
  43. }
  44. }
  45. private static var groupNameToValues: [String: [UserDefaultsAnyValue]] = [:]
  46. private static var valueKeyToGroupNames: [String: [String]] = [:]
  47. private static var groupNameToObservers: [String: [UUID: (UserDefaultsAnyValue, String) -> Void]] = [:]
  48. }
  49. // user default values group definitions
  50. extension UserDefaultsValueGroups {
  51. enum GroupNames {
  52. static let watchSync = "watchSync"
  53. static let alarm = "alarm"
  54. }
  55. }