Не уверен, возможно ли то, что я делаю, или я копаю себе яму и просто выбрал неправильный подход для этого. Попытка рефакторинга кода, чтобы иметь общий c способ чтения объектов из CoreData и преобразования их в соответствующие структуры. Единственное, что должно быть пользовательским, - это преобразование управляемого объекта в структуру. Ниже на игровой площадке приведен упрощенный образец того, что я до сих пор. Я пытаюсь получить данные последней строки, чтобы содержать массив структур UserDTO. Я не могу понять, как обеспечить, чтобы специализированный метод toDTO («Я в UserTranslator - toDTO») вызывался вместо «не реализованного» метода.
import UIKit
protocol DataTypeProtocol {
associatedtype DTO: Codable
}
protocol TranslatorDataProtocol {
associatedtype DataType:DataTypeProtocol
}
protocol TranslatorProtocol: TranslatorDataProtocol {
static func toDTO(from object:DataType)->DataType.DTO
}
struct UserDTO: Codable {}
struct RoleDTO: Codable {}
class User: DataTypeProtocol {
typealias DTO = UserDTO
//properties of User object
}
class Role: DataTypeProtocol {
typealias DTO = RoleDTO
//properties of User object
}
class Translator<DataType>:TranslatorProtocol where DataType: DataTypeProtocol {
static func toDTO(from object: DataType) -> DataType.DTO {
print(" I am in Translator - toDTO ")
preconditionFailure("subclass must implement")
}
func translate(from object:DataType)->DataType.DTO {
print(" I am in Translator - translate \(DataType.self)")
return Translator<DataType>.toDTO(from: object)
}
}
extension Translator where DataType: Role {
static func toDTO(from object: DataType) -> RoleDTO? {
print(" I am in Role - toDTO ")
return RoleDTO()
}
}
extension Translator where DataType: User {
static func toDTO(from object: DataType) -> UserDTO? {
print(" I am in UserTranslator - toDTO ")
return UserDTO()
}
}
class DataLayer<DataType>: TranslatorDataProtocol where DataType: DataTypeProtocol {
var translator = Translator<DataType>()
func loadData() -> [DataType.DTO] {
return self.loadFromDB().map({self.translator.translate(from:$0)})
}
func loadFromDB() -> [DataType] {
//force to return users - as if loaded from database
//force unwrap is for example purposes in actual code
//let entityName = String(describing:DataType.self)
//NSFetchRequest<DataType>(entityName: entityName)
return [User(),User(),User()] as! [DataType]
}
}
class UserModel: DataLayer<User> {
}
var userModel = UserModel()
let data = userModel.loadData()
В результате:
Я являюсь в переводчике - перевод пользователя
в переводчике - toDTO
фатальная ошибка: подкласс должен реализовать: файл MyPlayground.playground, строка 35