2017-10-12 4 views
2

J'ajoute du cache à mon application avec PINCache et je suis dans une situation où les méthodes déléguées pour encoder/décoder sont appelées par le système de cache. Ces méthodes sont génériques mais la valeur générique n'est pas conforme explicitement à Codable. Parce qu'ils sont des délégués, je ne peux pas modifier la signature pour rendre le type générique conforme à Codable.Swift 4 Codable & génériques

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) 
    } 
} 

Avec ce code, je vais avoir l'erreur suivante:

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

Comment puis-je forcer mon decoder à accepter la valeur générique?

+0

Pourriez-vous s'il vous plaît ajouter le code appelant la fonction 'modelForKey 'aussi bien? Merci;) –

Répondre

3

Depuis codable ne peut pas être mis en œuvre dans les extensions (encore?) Et depuis SimpleModel est interne à PINCache vous ne pouvez pas le rendre conforme aux Codable.

Si possible, je suggère de passer à une bibliothèque de mise en mémoire cache avec un protocole qui prend en charge codable comme Cache

0

Modifiez cette ligne pour vérifier qu'il est conforme aux Decodable:

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

Quelle est la différence avec mon code? Je vérifie déjà si 'T.self' est' Decodable'. – Morniak

+0

@Morniak où vérifiez-vous cela? – Paolo

+0

Dernière instruction de ma garde (ligne 2) – Morniak

2

Essayez func modelForKey<T : SimpleModel, Decodable> ... à exiger ce type est contraint à décodables.

0

IMO le problème n'est pas avec PINCache.

T.self is Codable ne dit pas le compilateur plus sur le type T, donc decoder.decode(T.self, from: data) ne passera pas la vérification de type, même si T est un Decodable.

Je pense que forcer RocketData sera la solution la plus simple ici (si vous voulez continuer à utiliser RocketData + Decodable et tous vos modèles sont conformes à Decodable). Rendre SimpleModel conforme à Decodable.

0
  1. Essayez de créer CustomProtocol: Codable, SimpleModel

  2. Si le point 1 ne fonctionne pas, essayez de créer classe personnalisée CustomClass: SimpleModel, Codable et utiliser modelForKey<T : CustomClass>

+1

Merci, je l'ai édité –