NSKeyedUnarchiver.decodeObject
приведет к сбою/SIGABRT
, если исходный класс неизвестен. Единственное решение, которое я видел, чтобы поймать этот вопрос, относится к ранней истории Swift и требует использования Objective C (также предваряется внедрением Swift 2 guard
, throws
, try
& catch
). Я мог бы выяснить маршрут Objective C, но, если возможно, я предпочел бы понять решение Swift.Быстрый способ только предотвратить отказ NSKeyedUnarchiver.decodeObject?
Например, данные были закодированы NSPropertyListFormat.XMLFormat_v1_0
. Следующий код будет сбой при unarchiver.decodeObject()
, если класс закодированных данных неизвестен.
//...
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
}
//...
Ищу для Swift 2 единственный способ проверить, является ли данные, прежде чем пытаться .decodeObject
- так .decodeObject
не имеет throws
- это значит, что try
- catch
, кажется, не быть одним из вариантов в Swift (методы без throws
нельзя обернуть AFAIK). Или альтернативный способ декодирования данных, которые будут вызывать ошибку, я могу поймать, если декодирование завершится неудачно. Я хочу, чтобы пользователь мог импортировать файл с диска iCloud или Dropbox, поэтому он должен быть правильно проверен. Я не могу предположить, что закодированные данные безопасны.
NSKeyedUnarchiver
В методы .unarchiveTopLevelObjectWithData
& .validateValue
оба имеют throws
. Возможно ли, что они могут быть использованы? Я не могу понять, как даже начать пытаться реализовать validateValue
в этом контексте. Это даже возможный маршрут? Или я должен смотреть на один из других методов решения?
Или кто-нибудь знает альтернативный вариант Swift 2 только для решения этой проблемы? Я считаю, что ключ, который меня интересует, вероятно, имеет название $classname
- но TBH Я не в своей глубине, пытаясь выяснить, как реализовать validateValue
- или даже будет ли это правильным путем для продолжения. У меня есть ощущение, что я упускаю что-то очевидное.
EDIT: Вот решение - спасибо, чтобы Ринтаро большой ответ (ов) ниже
Первоначальный ответ решен вопрос для меня - то есть реализации делегата.
На данный момент, однако я пошел с раствором, построенного вокруг дополнительного редактируемого ответ Ринтаро в следующем виде:
//...
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
}
//...
Большое спасибо. Это отличный ответ. – simons
См. Мой обновленный ответ. – rintaro
Еще раз спасибо. 'if try unarchiver.decodeTopLevelObject()! = nil' работает для меня так, как я его реализовал. Если это не «ноль», тогда мне хорошо идти. Я пропустил это при поиске методов, которые бросают. Ваш оригинальный ответ также работает для меня. – simons