Swift единственный способ предотвратить сбой NSKeyedUnarchiver.decodeObject?
NSKeyedUnarchiver.decodeObject
вызовет сбой /SIGABRT
если исходный класс неизвестен. Единственное решение, которое я видел, чтобы поймать эту проблему, относится к ранней истории Swift и требует использования Objective C (также предшествующей реализации Swift 2guard
, throws
, try
& catch
). Я мог бы найти маршрут Objective C - но я бы предпочел понять решение Swift-only, если это возможно.
Например - данные были закодированы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
- но ТБХ я не в силах разобраться, как реализоватьvalidateValue
- или даже будет ли это правильным путем продолжать. У меня такое чувство, что мне не хватает чего-то очевидного.
РЕДАКТИРОВАТЬ: Вот решение - благодаря отличным ответам 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
}
//...