summaryrefslogtreecommitdiffhomepage
path: root/ios/MullvadTypes/FileCache.swift
blob: 635d1e9c289512ab5e4de3819292ada642af11c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//
//  FileCache.swift
//  MullvadTypes
//
//  Created by Marco Nikic on 2023-05-30.
//  Copyright © 2023 Mullvad VPN AB. All rights reserved.
//

import Foundation

/// File cache implementation that can read and write any `Codable` content and uses file coordinator to coordinate I/O.
public struct FileCache<Content: Codable>: FileCacheProtocol {
    public let fileURL: URL

    public init(fileURL: URL) {
        self.fileURL = fileURL
    }

    public func read() throws -> Content {
        let fileCoordinator = NSFileCoordinator(filePresenter: nil)

        return try fileCoordinator.coordinate(readingItemAt: fileURL, options: [.withoutChanges]) { fileURL in
            try JSONDecoder().decode(Content.self, from: Data(contentsOf: fileURL))
        }
    }

    public func write(_ content: Content) throws {
        let fileCoordinator = NSFileCoordinator(filePresenter: nil)

        try fileCoordinator.coordinate(writingItemAt: fileURL, options: [.forReplacing]) { fileURL in
            try JSONEncoder().encode(content).write(to: fileURL)
        }
    }

    public func clear() throws {
        let fileCoordinator = NSFileCoordinator(filePresenter: nil)
        try fileCoordinator.coordinate(writingItemAt: fileURL, options: [.forDeleting]) { fileURL in
            try FileManager.default.removeItem(at: fileURL)
        }
    }
}

/// Protocol describing file cache that's able to read and write serializable content.
public protocol FileCacheProtocol<Content> {
    associatedtype Content: Codable

    func read() throws -> Content
    func write(_ content: Content) throws
    func clear() throws
}