hyperoslo / Cache

:package: Nothing but Cache.
Other
2.96k stars 335 forks source link

When retrieving object from Cache it throws error "keyNotFound". #303

Closed viktoryoo closed 5 months ago

viktoryoo commented 2 years ago

I have the following case:

I'm fetching from API, decoding the response to concrete model. After that the model gets store in Cache (HybridStorage). Everything is fine until I'm trying to retrieve the model from Cache. Because the model is Inherited from other model and I think that is the problem. The ModelCache is declared because I have a list of FootballCountryModel.

 public class RemapableObject: NSObject, Codable {

 }

 public class FootballCountryModel: RemapableObject {
    var id: String;
    var alias: String?;
    var countryCode: String?;
    var assets: CountryAssets?;
    var name: String;

    enum CodingKeys: String, CodingKey {
        case id, alias, assets, name;
        case countryCode = "country_code";
    }

    /*
     For a subclass of a class already adopting Codable (e.g. RemapableObject) we need to
     override our superclass's implementation by offering our own.
     There is no way for the compiler to synthesize an implementation here for us.
     */

    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self);

        self.id = try container.decode(String.self, forKey: .id);
        self.alias = try container.decode(String?.self, forKey: .alias);
        self.countryCode = try container.decode(String?.self, forKey: .countryCode);
        self.assets = try container.decode(CountryAssets?.self, forKey: .assets);
        self.name = try container.decode(String.self, forKey: .name);

        try super.init(from: container.superDecoder());
    }
}

class ModelCache<T: Codable>: NSObject, Codable {
    let data: [T];

    init (data: [T]) {
        self.data = data;
    }
}

Here is when Im trying to retrieve from Cache:

let diskConfig = DiskConfig(name: "FansUnitedSDK")
let memoryConfig = MemoryConfig(expiry: .never, countLimit: 10, totalCostLimit: 10)
let storage = try! Storage<String, ModelCache<FootballCountryModel>>(
          diskConfig: diskConfig,
          memoryConfig: memoryConfig,
          transformer: TransformerFactory.forCodable(ofType: ModelCache<FootballCountryModel>.self))
let cacheKey = "football_countries";
do {
        let footballCountriesCache = try storage.object(forKey: cacheKey) // Here it returns keyNotFound Error
} catch {
        print(error)
}

The keyNotFound Error is the following one:

keyNotFound(CodingKeys(stringValue: "id", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "object", intValue: nil), CodingKeys(stringValue: "data", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"id\", intValue: nil) (\"id\").", underlyingError: nil))

Any suggestions will be helpful. I'm trying for days to implement some caching in my project (with Core Data and other dependencies) but there always some issues coming up.

joeljfischer commented 2 years ago

I don't see any code where you are setting the object for that cacheKey to storage.

3lvis commented 5 months ago

Closing, reason outdated issue.