NSKeyedUnarchiver.decodeObject
verursacht einen Absturz/SIGABRT
, wenn die ursprüngliche Klasse unbekannt ist. Die einzige Lösung, die ich gesehen habe, um dieses Problem zu erfassen, stammt aus der frühen Geschichte von Swift und erforderte die Verwendung von Objective C (ebenfalls vorveraltete Swift 2-Implementierung von guard
, throws
, try
& catch
). Ich könnte die Objective-C-Route herausfinden - aber ich würde lieber eine Swift-only-Lösung verstehen, wenn möglich.Swift nur Weg, um NSKeyedUnarchiver.decodeObject Absturz zu verhindern?
Zum Beispiel - die Daten wurden mit NSPropertyListFormat.XMLFormat_v1_0
codiert. Der folgende Code schlägt bei unarchiver.decodeObject()
fehl, wenn die Klasse der codierten Daten unbekannt ist.
//...
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 suche einen Swift 2 einzige Möglichkeit, zu prüfen, ob die Daten, bevor .decodeObject
gültig ist - da .decodeObject
hat keine throws
- was bedeutet, dass try
-catch
keine Option in Swift zu sein scheint (Methoden ohne throws
kann AFAIK nicht gewickelt werden). Oder eine andere Möglichkeit, die Daten zu dekodieren, die einen Fehler erzeugen, den ich fangen kann, wenn die Decodierung fehlschlägt. Ich möchte, dass der Benutzer eine Datei vom iCloud-Laufwerk oder von Dropbox importieren kann. Daher muss er ordnungsgemäß validiert werden. Ich kann nicht davon ausgehen, dass die verschlüsselten Daten sicher sind.
Die NSKeyedUnarchiver
Methoden .unarchiveTopLevelObjectWithData
& .validateValue
haben beide throws
. Gibt es vielleicht einen Weg, wie diese genutzt werden könnten? Ich kann nicht herausfinden, wie man in diesem Zusammenhang überhaupt versucht, validateValue
zu implementieren. Ist das überhaupt eine mögliche Route? Oder sollte ich eine der anderen Methoden für eine Lösung suchen?
Oder kennt jemand eine Alternative Swift 2 nur um dieses Problem anzugehen? Ich glaube, dass der Schlüssel, an dem ich interessiert bin, wahrscheinlich $classname
heißt - aber TBH Ich bin in Bezug auf den Versuch, herauszufinden, wie man validateValue
implementieren kann - oder ob das der richtige Weg zum Durchhalten wäre. Ich habe das Gefühl, dass mir etwas offensichtlich fehlt.
EDIT: Hier ist eine Lösung - dank des Rintaro große Antwort (en) unter
Die erste Antwort für mich das Problem gelöst - das heißt, einen Delegierten zu implementieren.
//...
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
}
//...
Vielen Dank. Das ist eine großartige Antwort. – simons
Siehe meine aktualisierte Antwort. – rintaro
Danke nochmal. 'Wenn try unarchiver.decodeTopLevelObject()! = nil' funktioniert für mich so wie ich es implementiert habe. Wenn es nicht "nil" ist, dann bin ich gut zu gehen. Das habe ich vermisst, als ich nach Methoden suchte, die werfen. Deine ursprüngliche Antwort funktioniert auch für mich. – simons