UserDefaultsValueGroups.swift 2.3 KB

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