// Записывает `data` в файл с именем `file`.

Для дискового кеша произвольный T нужно уметь сериализовать. Один вариант — ограничить T протоколом Codable и хранить JSON по безопасному имени файла.

Короткий ответ

Что ответить на собеседовании

Для дискового кеша произвольный T нужно уметь сериализовать. Один вариант — ограничить T протоколом Codable и хранить JSON по безопасному имени файла.

Подробный разбор

Ответ с пояснениями

Условие

// Записывает data в файл с именем file. func writeData(_ data: Data, to file: String) { let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let fileURL = documentDirectoryURL.appendingPathComponent(file) try? data.write(to: fileURL) }

// Удаляет файл с именем file. func remove(file: String) { let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let fileURL = documentDirectoryURL.appendingPathComponent(file) try? FileManager.default.removeItem(at: fileURL) }

// Читает Data из файла с именем file. Если файл не существует, возвращает nil. func readData(from file: String) -> Data? { let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let fileURL = documentDirectoryURL.appendingPathComponent(file) return try? Data(contentsOf: fileURL) }

final class DiskCache<T>: CacheProtocol { func setValue(_ value: T?, forKey key: String) {

}
func getValue(forKey key: String) -> T? {
    
}
func fetchValue(forKey key: String, completion: @escaping (T?) -> Void) {
    
}

}

Ответ

Для дискового кеша произвольный T нужно уметь сериализовать. Один вариант — ограничить T протоколом Codable и хранить JSON по безопасному имени файла.

Если CacheProtocol требует показанные getValue/setValue/fetchValue, реализация поверх данных функций может быть такой:

import Foundation
import CryptoKit

final class DiskCache<T: Codable>: CacheProtocol {
    private func filename(_ key: String) -> String {
        let hash = SHA256.hash(data: Data(key.utf8))
        return hash.map { String(format: "%02x", $0) }.joined()
    }
    func setValue(_ value: T?, forKey key: String) {
        guard let value else { remove(file: filename(key)); return }
        guard let data = try? JSONEncoder().encode(value) else { return }
        writeData(data, to: filename(key))
    }
    func getValue(forKey key: String) -> T? {
        guard let data = readData(from: filename(key)) else { return nil }
        return try? JSONDecoder().decode(T.self, from: data)
    }
    func fetchValue(forKey key: String,
                    completion: @escaping (T?) -> Void) {
        completion(getValue(forKey: key))
    }
}

Это синхронный учебный вариант, без защиты конкурентного доступа. Полный протокол в условии отсутствует: если он требует value(forKey:), имя нужно согласовать. Для production нужны каталог кеша, атомарная запись и передача ошибок; исходные helpers скрывают ошибки через try?. Дисковые операции нельзя выполнять в UI-пути на главном потоке.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее