Storage.swift 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import Foundation
  2. import Dispatch
  3. /// Manage storage. Use memory storage if specified.
  4. /// Synchronous by default. Use `async` for asynchronous operations.
  5. public final class Storage<T> {
  6. /// Used for sync operations
  7. private let syncStorage: SyncStorage<T>
  8. private let asyncStorage: AsyncStorage<T>
  9. private let hybridStorage: HybridStorage<T>
  10. /// Initialize storage with configuration options.
  11. ///
  12. /// - Parameters:
  13. /// - diskConfig: Configuration for disk storage
  14. /// - memoryConfig: Optional. Pass config if you want memory cache
  15. /// - Throws: Throw StorageError if any.
  16. public convenience init(diskConfig: DiskConfig, memoryConfig: MemoryConfig, transformer: Transformer<T>) throws {
  17. let disk = try DiskStorage(config: diskConfig, transformer: transformer)
  18. let memory = MemoryStorage<T>(config: memoryConfig)
  19. let hybridStorage = HybridStorage(memoryStorage: memory, diskStorage: disk)
  20. self.init(hybridStorage: hybridStorage)
  21. }
  22. /// Initialise with sync and async storages
  23. ///
  24. /// - Parameter syncStorage: Synchronous storage
  25. /// - Paraeter: asyncStorage: Asynchronous storage
  26. public init(hybridStorage: HybridStorage<T>) {
  27. self.hybridStorage = hybridStorage
  28. self.syncStorage = SyncStorage(
  29. storage: hybridStorage,
  30. serialQueue: DispatchQueue(label: "Cache.SyncStorage.SerialQueue")
  31. )
  32. self.asyncStorage = AsyncStorage(
  33. storage: hybridStorage,
  34. serialQueue: DispatchQueue(label: "Cache.AsyncStorage.SerialQueue")
  35. )
  36. }
  37. /// Used for async operations
  38. public lazy var async = self.asyncStorage
  39. }
  40. extension Storage: StorageAware {
  41. public func entry(forKey key: String) throws -> Entry<T> {
  42. return try self.syncStorage.entry(forKey: key)
  43. }
  44. public func removeObject(forKey key: String) throws {
  45. try self.syncStorage.removeObject(forKey: key)
  46. }
  47. public func setObject(_ object: T, forKey key: String, expiry: Expiry? = nil) throws {
  48. try self.syncStorage.setObject(object, forKey: key, expiry: expiry)
  49. }
  50. public func removeAll() throws {
  51. try self.syncStorage.removeAll()
  52. }
  53. public func removeExpiredObjects() throws {
  54. try self.syncStorage.removeExpiredObjects()
  55. }
  56. }
  57. public extension Storage {
  58. func transform<U>(transformer: Transformer<U>) -> Storage<U> {
  59. return Storage<U>(hybridStorage: hybridStorage.transform(transformer: transformer))
  60. }
  61. }
  62. extension Storage: StorageObservationRegistry {
  63. @discardableResult
  64. public func addStorageObserver<O: AnyObject>(
  65. _ observer: O,
  66. closure: @escaping (O, Storage, StorageChange) -> Void
  67. ) -> ObservationToken {
  68. return hybridStorage.addStorageObserver(observer) { [weak self] observer, _, change in
  69. guard let strongSelf = self else { return }
  70. closure(observer, strongSelf, change)
  71. }
  72. }
  73. public func removeAllStorageObservers() {
  74. hybridStorage.removeAllStorageObservers()
  75. }
  76. }
  77. extension Storage: KeyObservationRegistry {
  78. @discardableResult
  79. public func addObserver<O: AnyObject>(
  80. _ observer: O,
  81. forKey key: String,
  82. closure: @escaping (O, Storage, KeyChange<T>) -> Void
  83. ) -> ObservationToken {
  84. return hybridStorage.addObserver(observer, forKey: key) { [weak self] observer, _, change in
  85. guard let strongSelf = self else { return }
  86. closure(observer, strongSelf, change)
  87. }
  88. }
  89. public func removeObserver(forKey key: String) {
  90. hybridStorage.removeObserver(forKey: key)
  91. }
  92. public func removeAllKeyObservers() {
  93. hybridStorage.removeAllKeyObservers()
  94. }
  95. }