Пожалуйста, обратитесь к упрощенному вопросу здесь, этот вопрос ниже кажется слишком длинным. Упрощенная версия: iOS: Как использовать декодируемый для класса модели с переменной типа протокол
Вопрос: Как передать объект класса, который имеет другой объект пользовательского класса введите as varaible со стороны проекта на сторону фреймворка / модуля, чтобы сторона фреймворка / модуля могла использовать этот объект.
Мой подход: Я написал протокол на стороне модуля с такой же сигнатурой модели на сторона проекта и, таким образом, передача объекта со стороны проекта на сторону модуля работает, если модель имеет все встроенные типы, такие как Strings и Ints, но не работает, если модель имеет пользовательский тип. Подробное объяснение проблемы: (ниже я даю фрагмент кода). A: У меня есть класс модели, называющий его MyModel, с несколькими встроенными типами переменных, такими как String, одна переменная имеет пользовательский тип, т.е. другое имя класса OtherModel. Класс MyModel реализует Decodable, поэтому при получении ответа json MyModel правильно заполняется вместе с пользовательской переменной внутри него OtherModel, поскольку OtherModel также реализует Decodable. Пока все хорошо.
B: Примечание. MyModel и OtherModel находятся на стороне проекта, который необходимо использовать на стороне модуля.
C: Теперь есть модуль или платформа, в которую мы переносим код, но пока не можем перенести MyModel. Поэтому в модуле я не могу использовать класс MyModel. Поэтому я сделал обходной путь в pod, я создал протокол с именем MyModelProtocol и точно определил все переменные MyModel, но прокомментировал переменную пользовательского типа OtherModel. Теперь на стороне проекта я сделал расширение MyModel class inheirit из этого протокола MyModelProtocol , определенного в рамках. Таким образом, с помощью этого обходного пути я могу передать объект MyModel, подобный этому VC1.setup(model: myModel)
, стороне фреймворка, которая получает это в VC1 public func setup(model:MyModelProtocol)
. Все это хорошо работает. Я могу использовать объект, и он встроен в ivars.
D: Проблема возникает, когда я пытаюсь использовать пользовательскую переменную типа OtherModelProtocol в классе MyModel. Я должен использовать этот пользовательский тип OtherModelProtocol, потому что он виден на стороне Pod, и поэтому со стороны проекта MyModel может иметь вложенный объект OtherModel, передаваемый на сторону Pod с использованием имени OtherModelProtocol, OtherModel на стороне проекта имеет расширение, которое наследует этот протокол. OtherModelProtocol На стороне Pod у OtherModelProtocol есть точные переменные, такие как OtherModel и все строковые переменные. Но теперь я не могу использовать или передать MyModel, потому что компилятор выдает ошибку. Компилятор не знает, как создать объект для типа OtherModelProtocol, сидящего в MyModel.
COMPILER жалуется
Type 'MyModel' does not conform to protocol 'Decodable'
Protocol requires initializer 'init(from:)' with type 'Decodable'
Cannot automatically synthesize 'Decodable' because 'OtherModelProtocol' does not conform to
'Decodable'
1: Сторона проекта - класс MyModel
class MyModel: NSObject, NSCopying, Decodable {
var id: Int?
var name: String?
// This is problem field
var otherModel: MyPod.OtherModelProtocol? = nil
init(id: Int?, name: String?, otherModel: MyPod.OtherModelProtocol?) {
self.id = id
self.name = name
self.otherModel = otherModel
}
// This is for decoding
enum CodingKeys: String, Swift.CodingKey
{
case id
case name = "shopName"
case otherModel
}
} // **** End of class MyModel ****
2: Сторона проекта - расширение класса MyModel
// **** Extension of MyModel so it can be passed to pod folder, MyModelProtocol is defined in pod with exact same variables as MyModel *****
extension MyModel: Pod.MyModelProtocol {
}
3: Сторона проекта - класс OtherModel
// **** OtherModel ****
class OtherModel: NSObject, Decodable {
var employeeID: String?
var employeeName: String?
init(employeeID: String?, employeeName: String?) {
self.employeeID = employeeID
self.employeeName = employeeName
}
enum AdditionalInfoKeys: String, CodingKey {
case employeeID
case employeeName
}
}
4: Сторона проекта - расширение OtherModel
// **** Extension of OtherModel so it can be passed to pod folder, OtherModelProtocol is defined in pod with exact same variables as OtherModel *****
extension OtherModel: Pod.OtherModelProtocol {
}
5: Сторона Pod - MyModelProtocol
// **** POD Side *****
public protocol MyModelProtocol {
var id: Int? { get }
var name: String? { get }
/ **** Refrence to otherModelProtocol ****
var otherModel: OtherModelProtocol { get }// OtherModelProtocol is defined in same pod.
}
6: Сторона Pod - OtherModelProtocol
// ***** POD Side OtherModelProtocol ****
public protocol OtherModelProtocol {
var employeeName: String? { get }
var employeeID: String? { get }
}