Я обертываю объекты Core Data в структуры, чтобы сделать их Codable.
[NB: Прежде чем вы направите меня к написанию файла swift для каждого класса Core Data, я бы хотел сказать, что перенос дочерних объектов NSManagedObject является результатом сознательного выбора в пользу удобства сопровождения кода, поскольку модель данных можетразвиваться в будущем.]
У меня есть несколько таких классов, вот пример:
struct CodableNeed : Codable {
enum CodingKeys: String, CodingKey {
...
}
var need:Need
init (_ need:Need) {
self.need = need
}
init(from decoder: Decoder) throws {
....
}
func encode(to encoder: Encoder) throws {
....
}
}
На самом деле это работает довольно хорошо, как любое обновление в init (from: decoder)) структуры фактически хранится в ManagedObjectContext.
Чтобы каждый экземпляр класса NSManagedObject мог возвращать свою собственную структуру, я определил протокол, в котором каждый экземпляр класса может возвращать свою собственную структуру Codable:
protocol CodableWhenWrapped {
func wrapToCodable() -> Codable
}
extension Need : CodableWhenWrapped {
func wrapToCodable() -> Codable {
return CodableNeed(self)
}
}
Затем я использую это в функции кодирования:
func jsonDataOfCodable<T:Encodable>(_ object:T) throws -> Data {
let encoder = JSONEncoder()
let data = try encoder.encode(object)
return data
}
и вызываю эту функцию для генерации URLSessionUploadTask
:
func updateTaskFor<T: NSManagedObject> (_ object:T, withSession session:URLSession) throws -> URLSessionUploadTask
where T: CodableWhenWrapped
{
let encoder = JSONEncoder()
// Here is the compile error:
// " Cannot invoke 'jsonDataOfCodable' with an argument list of type '(Codable)' "
let jsonData = try jsonDataOfCodable(object.wrapToCodable())
// then continue with generating the uploadTask
let url = "https://myurl.com/"
let request = URLRequest(url: url)
let updateTask = session.uploadTask(with: request, from: jsonData) { (data, response, error) in
....
}
}
Вот проблема: кодне компилируется при вызове jsonDataOfCodable
: Cannot invoke 'jsonDataOfCodable' with an argument list of type '(Codable)'
.
Есть идеи, почему компилятору это не нравится?
Обратите внимание, что у меня возникает та же проблема, когда я задаю <T:Codable>
вместо <T:Encodable>
в прототипе jsonDataOfCodable
.