diff options
Diffstat (limited to 'ios/RelayCache')
| -rw-r--r-- | ios/RelayCache/CachedRelays.swift | 8 | ||||
| -rw-r--r-- | ios/RelayCache/RelayCache.swift | 81 |
2 files changed, 19 insertions, 70 deletions
diff --git a/ios/RelayCache/CachedRelays.swift b/ios/RelayCache/CachedRelays.swift index 6ff9c36091..499eb9cde3 100644 --- a/ios/RelayCache/CachedRelays.swift +++ b/ios/RelayCache/CachedRelays.swift @@ -10,15 +10,15 @@ import Foundation import MullvadREST /// A struct that represents the relay cache on disk -public struct CachedRelays: Codable { +public struct CachedRelays: Codable, Equatable { /// E-tag returned by server - public var etag: String? + public let etag: String? /// The relay list stored within the cache entry - public var relays: REST.ServerRelaysResponse + public let relays: REST.ServerRelaysResponse /// The date when this cache was last updated - public var updatedAt: Date + public let updatedAt: Date public init(etag: String? = nil, relays: REST.ServerRelaysResponse, updatedAt: Date) { self.etag = etag diff --git a/ios/RelayCache/RelayCache.swift b/ios/RelayCache/RelayCache.swift index 3c5ceb3a20..abce823786 100644 --- a/ios/RelayCache/RelayCache.swift +++ b/ios/RelayCache/RelayCache.swift @@ -8,30 +8,26 @@ import Foundation import MullvadREST +import MullvadTypes public final class RelayCache { - /// Cache file location. - let cacheFileURL: URL + private let fileCache: any FileCacheProtocol<CachedRelays> - /// Location of pre-bundled relays file. - let prebundledRelaysFileURL: URL - - /// Initialize cache with default cache file location in app group container. - public init?(securityGroupIdentifier: String) { - guard let containerURL = FileManager.default.containerURL( - forSecurityApplicationGroupIdentifier: securityGroupIdentifier - ), let prebundledRelaysFileURL = Bundle(for: Self.self) - .url(forResource: "relays", withExtension: "json") else { return nil } + /// Designated initializer + public init(cacheDirectory: URL) { + fileCache = FileCache(fileURL: cacheDirectory.appendingPathComponent("relays.json", isDirectory: false)) + } - cacheFileURL = containerURL.appendingPathComponent("relays.json", isDirectory: false) - self.prebundledRelaysFileURL = prebundledRelaysFileURL + /// Initializer that accepts a custom FileCache implementation. Used in tests. + init(fileCache: some FileCacheProtocol<CachedRelays>) { + self.fileCache = fileCache } /// Safely read the cache file from disk using file coordinator and fallback to prebundled /// relays in case if the relay cache file is missing. public func read() throws -> CachedRelays { do { - return try readDiskCache() + return try fileCache.read() } catch { if error is DecodingError || (error as? CocoaError)?.code == .fileReadNoSuchFile { return try readPrebundledRelays() @@ -43,63 +39,16 @@ public final class RelayCache { /// Safely write the cache file on disk using file coordinator. public func write(record: CachedRelays) throws { - var result: Result<Void, Error>? - let fileCoordinator = NSFileCoordinator(filePresenter: nil) - - let accessor = { (fileURLForWriting: URL) in - result = Result { - let data = try JSONEncoder().encode(record) - try data.write(to: fileURLForWriting) - } - } - - var error: NSError? - fileCoordinator.coordinate( - writingItemAt: cacheFileURL, - options: [.forReplacing], - error: &error, - byAccessor: accessor - ) - - if let error { - result = .failure(error) - } - - try result?.get() - } - - /// Safely read the cache file from disk using file coordinator. - private func readDiskCache() throws -> CachedRelays { - var result: Result<CachedRelays, Error>? - let fileCoordinator = NSFileCoordinator(filePresenter: nil) - - let accessor = { (fileURLForReading: URL) in - result = Result { - let data = try Data(contentsOf: fileURLForReading) - return try JSONDecoder().decode(CachedRelays.self, from: data) - } - } - - var error: NSError? - fileCoordinator.coordinate( - readingItemAt: cacheFileURL, - options: [.withoutChanges], - error: &error, - byAccessor: accessor - ) - - if let error { - result = .failure(error) - } - - return try result!.get() + try fileCache.write(record) } /// Read pre-bundled relays file from disk. private func readPrebundledRelays() throws -> CachedRelays { + guard let prebundledRelaysFileURL = Bundle(for: Self.self).url(forResource: "relays", withExtension: "json") + else { throw CocoaError(.fileNoSuchFile) } + let data = try Data(contentsOf: prebundledRelaysFileURL) - let relays = try REST.Coding.makeJSONDecoder() - .decode(REST.ServerRelaysResponse.self, from: data) + let relays = try REST.Coding.makeJSONDecoder().decode(REST.ServerRelaysResponse.self, from: data) return CachedRelays( relays: relays, |
