iOS: Как передать декодируемый объект модели, который имеет пользовательский тип, т.е. другой вложенный объект модели. Как перейти на сторону стручка - PullRequest
0 голосов
/ 29 февраля 2020

Пожалуйста, обратитесь к упрощенному вопросу здесь, этот вопрос ниже кажется слишком длинным. Упрощенная версия: 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 }
}
...