Swift: вызов специализированного метода, определенного в расширении протокола - PullRequest
0 голосов
/ 17 января 2020

Не уверен, возможно ли то, что я делаю, или я копаю себе яму и просто выбрал неправильный подход для этого. Попытка рефакторинга кода, чтобы иметь общий 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...