NSKeyedUnarchiver.decodeObject
приведет к сбою / SIGABRT
, если исходный класс неизвестен. Единственное решение, которое я видел, чтобы поймать этот вопрос, относится к ранней истории Swift и требует использования Objective C (также предваряется реализацией Swift 2 guard
, throws
, try
и catch
). Я мог бы выяснить маршрут Objective C, но я предпочел бы, если возможно, понять решение Swift.
Например, данные были закодированы с помощью 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: вот решение - благодаря отличному ответу rintaro ниже
Первоначальный ответ решил проблему для меня - т.е. реализацию делегата.
В настоящее время, однако, я пошел с решением, построенным вокруг дополнительного отредактированного ответа rintaro следующим образом:
//...
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
}
//...