summaryrefslogtreecommitdiffhomepage
path: root/ios/RelayCache/RelayCache.swift
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2023-06-13 16:40:54 +0200
committerAndrej Mihajlov <and@mullvad.net>2023-06-13 16:40:54 +0200
commit64ae1f81ad328e7e179eea9e49b3dbf96e910dce (patch)
treee527fc18d4eff5699bad03b7acbb685972a2b5fd /ios/RelayCache/RelayCache.swift
parent7448427f811daf99dd4ab9d4f3676f354beff245 (diff)
parentb6a59eb7d162c97dd8827eeed46cfca7d2eef171 (diff)
downloadmullvadvpn-64ae1f81ad328e7e179eea9e49b3dbf96e910dce.tar.xz
mullvadvpn-64ae1f81ad328e7e179eea9e49b3dbf96e910dce.zip
Merge branch 'enable-shadowsocks-relay-caching-ios-185'
Diffstat (limited to 'ios/RelayCache/RelayCache.swift')
-rw-r--r--ios/RelayCache/RelayCache.swift81
1 files changed, 15 insertions, 66 deletions
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,