UserDefaultsValueGroups.swift 2.5 KB

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