J'essaye actuellement de décoder la liste de propriété en utilisant le protocole PropertyListEncoder et Swift 4 Codable.

J'ai essayé quelques types de base (Strings, Ints, ..) et tout cela fonctionne très bien, mais je ne suis pas capable de décoder l'URL. J'ai lu plusieurs articles sur ce sujet et je suis sûr que cela devrait fonctionner. Cependant, l'exemple suivant échoue le décodage avec cette erreur:

Expected to decode Dictionary<String, Any> but found a string/data instead.

Je pense que cela fonctionne correctement avec les fichiers .json et je n'ai trouvé aucune information sur le support différent pour les types codables dans JSONDecoder et PropertyListDecoder. Cela pourrait-il être causé par l'incompatibilité de l'analyseur?

J'utilise Xcode 9.1 et Swift 4.0.2.

Échantillon .plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>web</key>
        <string>https://link.to</string>
    </dict>
</plist>

Exemple de code Swift:

struct Info: Codable {
   let web: URL
}

func loadInfo() {
    let propertiesDecoder = PropertyListDecoder()
    let data = try! Data(contentsOf:
        Bundle.main.url(forResource: "web", withExtension: "plist")!)

    try! propertiesDecoder.decode(Info.self, from: data)
}

Merci pour toute aide!

3
josefdolezal 27 nov. 2017 à 23:44

3 réponses

Meilleure réponse

Comme vous pouvez dans le XML brut, il est stocké sous forme de chaîne. Les plists AFAIK ne prennent pas en charge les URL. Cela devrait fonctionner si vous changez simplement web en String.

Si vous devez utiliser la propriété comme URL, je vous suggère d'utiliser une propriété calculée:

var webURL: URL? {
    //return your url
}
0
NoLongerContributingToSE 27 nov. 2017 à 20:51

Comme je peux le voir, la clé web a une valeur de type String, nous devons donc conserver un type correspondant

Mais pour obtenir la chaîne en tant que URL, nous devons ajouter une variable calculée et peut-être pour l'optimiser un peu, nous pouvons rendre la variable paresseuse, c'est-à-dire qu'elle sera calculée une fois quand c'est nécessaire

La jambe de force modifiée ressemblerait à ceci:

struct Info: Codable {
    let web: String

    lazy var url: URL? = { return URL(string: web) }()
}
1
zombie 27 nov. 2017 à 21:28
47519502