Swift nur um zu verhindern, dass NSKeyedUnarchiver.decodeObject abstürzt?

NSKeyedUnarchiver.decodeObject verursacht einen Absturz /SIGABRT wenn die original-Klasse unbekannt ist. Die einzige Lösung, die ich gesehen habe, fangen diese Ausgabe stammt aus dem Swift-Frühgeschichte Bedarf mit Objective C (auch pre-datiert Swift 2 ist die Implementierung von guard, throws, try & catch). Ich konnte herausfinden, das Ziel C-route - aber ich würde es vorziehen, zu verstehen, eine Rasche Lösung wenn möglich.

Zum Beispiel - die Daten wurden codiert mit NSPropertyListFormat.XMLFormat_v1_0. Der folgende code wird nicht auf unarchiver.decodeObject() wenn die Klasse von den verschlüsselten Daten ist unbekannt.

//...
let dat = NSData(contentsOfURL: url)!
let unarchiver = NSKeyedUnarchiver(forReadingWithData: dat)

//it will crash after this if the class in the xml file is not known

if let newListCollection = (unarchiver.decodeObject()) as? List {
    return newListCollection
} else {
    return nil
}
//...

Ich bin auf der Suche nach einem Swift 2 einzige Weg, um zu testen, ob die Daten gültig sind, bevor Sie versuchen .decodeObject - da .decodeObject hat keine throws - was bedeutet, dass try - catch scheint nicht eine option in Swift (Methoden ohne throws können nicht eingewickelt werden, AFAIK). Oder sonst eine alternative Möglichkeit der Decodierung der Daten, die wirft einen Fehler kann ich abfangen, wenn das Dekodieren fehlschlägt. Ich möchte die Benutzer in der Lage sein, um den import einer Datei von iCloud drive oder Dropbox - daher muss es ordnungsgemäß validiert werden. Ich kann nicht davon ausgehen, dass die codierten Daten sicher.

Den NSKeyedUnarchiver Methoden .unarchiveTopLevelObjectWithData & .validateValue beide haben throws. Gibt es vielleicht einen Weg, dass diese genutzt werden könnten? Ich kann nicht herausfinden, wie Sie selbst beginnen, zu versuchen, zu implementieren validateValue in diesem Zusammenhang. Ist das auch ein denkbarer Weg? Oder sollte ich suchen, um eine der anderen Methoden für eine Lösung?

Oder kennt jemand ein Alternatives Swift 2 nur die Art der Auseinandersetzung mit diesem Thema? Ich glaube, dass der Schlüssel ich bin interessiert, ist wohl berechtigt $classname - aber TBH, ich bin aus meiner Tiefe mit Bezug zu versucht, herauszufinden, wie die Umsetzung validateValue - oder ob sogar das wäre die richtige Strecke durchzuhalten. Ich habe das Gefühl, dass mir etwas fehlt offensichtlich.


EDIT: Hier ist eine Lösung - Dank rintaro ist toll, die Antwort(en) unten

Die erste Antwort das Problem gelöst, für mich - also die Implementierung einer delegate.

Jetzt aber ich habe eine Lösung gebaut, um rintaro zusätzlich bearbeitet Reaktion wie folgt:

//...
let dat = NSData(contentsOfURL: url)!
let unarchiver = NSKeyedUnarchiver(forReadingWithData: dat)

do {
    let decodedDataObject = try unarchiver.decodeTopLevelObject()
    if let newListCollection = decodedDataObject as? List {
        return newListCollection
    } else {
        return nil
    }
}
catch {
    return nil
}
//...

InformationsquelleAutor der Frage simons | 2015-10-02

Schreibe einen Kommentar