Это очень похоже на этот вопрос: Как я могу декодировать объект, когда исходный класс недоступен? , но как лучше всего это сделать, если данные, которые я разархивирую, могут соответствовать любому классу? к определенному протоколу?
В качестве простого примера,
protocol TestProtocol: NSCoding { }
class A: TestProtocol { }
class B: TestProtocol { }
class C: TestProtocol { }
// And 20 more classes
...
let data = UserDefaults.standard.object(forKey: "TestKey") as! Data
NSKeyedUnarchiver.setClass(<SomeClassConformingToTestProtocol?>, forClassName: String(describing: <SomeClassConformingToTestProtocol>)) // No class to pass in here, but protocol is known.
NSKeyedUnarchiver.unarchiveObject(with: data) as! TestProtocol
Я мог бы перебрать все классы и вызвать
NSKeyedUnarchiver.setClass(A.self, forClassName: "A")
NSKeyedUnarchiver.setClass(B.self, forClassName: "B")
NSKeyedUnarchiver.setClass(C.self, forClassName: "C")
Но это означает, что когда есть новыйкласс в TestProtocol
, он должен быть добавлен в этот список и кажется неисполнимым.
Я попытался переопределить classFallbacksForKeyedArchiver()
для предоставления запасного имени класса, если исходный класс не найден, но это все ещевыдает NSInvalidUnarchiveOperationException
при разархивировании в расширении общего ресурса моего проекта.
Есть ли лучший способ сделать это, кроме как забыть добавить классы в массив при создании нового класса (соответствующего протоколу)?