2017-10-12 15 views
2

私はPINCacheを使用してアプリケーションにキャッシュを追加しています。私は、キャッシュシステムによってエンコード/デコードするデリゲートメソッドが呼び出される状況にあります。 これらのメソッドは汎用ですが、汎用値は明示的にCodableに適合しません。彼らは代理人であるため、署名を変更して汎用タイプをCodableに一致させることはできません。このコードではSwift 4 Codable&generics

func modelForKey<T : SimpleModel>(_ cacheKey: String?, context: Any?, completion: @escaping (T?, NSError?) ->()) { 
    guard let cacheKey = cacheKey, let data = cache.object(forKey: cacheKey) as? Data, T.self is Codable else { 
     completion(nil, nil) 
     return 
    } 

    let decoder = JSONDecoder() 
    do { 
     let model: T = try decoder.decode(T.self, from: data) 
     completion(model, nil) 
    } catch { 
     completion(nil, nil) 
    } 
} 

、私は次のエラーを持っている:

In argument type T.Type , T does not conform to expected type Decodable

は、どのように私は、一般的な値を受け入れるように、私のdecoderを強制することができますか?

guard let cacheKey = ... as? Data, T.self is Decodable else { 
+0

を使用しようとCustomProtocol: Codable, SimpleModel

  • を作成するようにしてください 'も同様ですか?ありがとう;) –

  • 答えて

    3

    コード可能な拡張機能で実装することができません(まだ?)とSimpleModelがPINCacheの内部にあるので、あなたはそれが準拠することはできませんので:

    0

    変更この行は、それがDecodableに準拠していることを確認しますコーディング可能な

    可能であれば、私はそのタイプが復号可能に拘束されて要求するようにfunc modelForKey<T : SimpleModel, Decodable> ...を試してみてくださいCache

    +0

    私のコードとの違いは何ですか?私はすでに 'Telfelf'が' Decodable'であるかどうかをチェックしています。 – Morniak

    +0

    @Morniakどこをチェックしていますか? – Paolo

    +0

    私のガードの最後の指示(2行目) – Morniak

    2

    のようなコード可能なをサポートするプロトコルで、キャッシュライブラリに切り替えることをお勧め。

    0

    IMO PINCacheに問題がありません。

    T.self is CodableはタイプT詳細コンパイラを教えてくれないので、decoder.decode(T.self, from: data)TDecodable場合でも、型チェックをパスしません。

    私はRocketDataをフォークするのが最も簡単な解決策になると思います(RocketData + Decodableを使い続け、すべてのモデルがDecodableに準拠している場合)。 SimpleModelDecodableに従ってください。

    0
    1. あなたが関数 `modelForKeyを呼び出すコードを追加してもらえポイント1が動作しない場合は、カスタムクラスCustomClass: SimpleModel, Codableを作成し、modelForKey<T : CustomClass>

    +1

    ありがとう、私はそれを編集しました –