Swift 4 kodierbar decode URL aus String

Ich bin derzeit versuchen zu entschlüsseln, Property-Liste mit PropertyListEncoder und Swift 4 Codable Protokoll.

Ich habe versucht, einige grundlegende Typen (Strings, Ints,…) und diese funktioniert alles ganz gut, aber ich bin nicht in der Lage decode URL. Ich Las mehrere Artikel über dieses Thema und ich bin mir ziemlich sicher das sollte einfach funktionieren. Jedoch, das folgende Beispiel schlägt fehl, die Entschlüsselung mit diesem Fehler:

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

Ich denke, diese funktioniert einwandfrei mit .json Dateien und ich didn ‚ T finden Sie alle Informationen über die verschiedenen support für kodierbar Arten in JSONDecoder und PropertyListDecoder. Könnte dies verursacht werden durch parser Inkompatibilität?

Ich bin mit Xcode 9.1 und Swift 4.0.2.

Probe .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>

Probe Swift-code:

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

Vielen Dank für jede Hilfe!!!

InformationsquelleAutor josefdolezal | 2017-11-27



3 Replies
  1. 0

    Wie Sie in der xml-Rohdaten, diese wird als string gespeichert. AFAIK plists nicht support-URLs. Es sollte funktionieren, wenn du einfach ändern web zu einem String.

    Wenn Sie müssen, verwenden Sie die Eigenschaft als URL, ich würde vorschlagen, mit einer berechneten Eigenschaft:

    var webURL: URL? {
        //return your url
    }
    • Danke für die schnelle Antwort! Ich wurde gefragt, weil in JSON-Strings behandelt werden dürfen als URL, das folgende Objekt wäre korrekt analysiert: { „web“: „link.zu“ } ich habe gehofft, dass plist-Strings werden können, welche auf diese Weise auch. Nochmals vielen Dank für die Klarstellung!
  2. 16

    Können Sie eine Speicherung von URLs in Listen, und verwenden Sie die Standard-Decodable Umsetzung.

    Basiert auf der Umsetzung der Decodable Protokoll init in der Swift-standard-Bibliothek, die Sie speichern müssen Sie die URL wie ein Wörterbuch in der Plist, in der ein Schlüssel mit dem Namen „relative“. Optional können Sie auch eine verschachtelte URL-Wörterbuch mit dem Namen „base“ im Wörterbuch. Diese beiden Werte übergeben bekommen, um die URL(string: relative, relativeTo: base) Konstruktor bei der Dekodierung.

    Beispiel:

    <?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">
    <array>
        <dict>
            <key>apiHost</key>
            <dict>
                <key>relative</key>
                <string>https://example.com/api/v0</string>
            </dict>
            <key>otherKey</key>
            <string>SomeValue</string>
           </dict>
     </array>
     </plist>

    Diese Plist-Dekodierung mit den folgenden:

    struct PlistItem: Codable {
        let apiHost: URL
        let otherKey: String
    }
    guard let filePath = Bundle.main.url(forResource: "Data", withExtension: "plist") else { return }
    do {
        let data = try Data(contentsOf: filePath)
        let decoder = PropertyListDecoder()
        let values = try decoder.decode([PlistItem].self, data)
    }
    catch { }
    • Danke. Dies sollte akzeptiert werden Antwort!
  3. 0

    Wie kann ich den key sehen web hat einen Wert vom Typ String so dass wir benötigen, um einen passenden Typ

    Aber, um die Zeichenfolge als URL dann müssen wir hinzufügen, eine berechnete variable und vielleicht zu optimieren, ein wenig können wir die variable faul ich.e es wird einmal berechnet, wenn es erforderlich ist

    Den bearbeiteten Federbein würde dann so Aussehen:

    struct Info: Codable {
        let web: String
    
        lazy var url: URL? = { return URL(string: web) }()
    }

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.