Использование в качестве конкретного типа, соответствующего протоколу, не поддерживается - PullRequest
0 голосов
/ 19 мая 2018

Я хочу создать универсальный контроллер вида для страницы настроек.Прямо сейчас настройки исходят из JSON, но реализация может быть отключена позже, поэтому я хочу иметь протоколы.Например, протокол LanguageSetting пуст, но с его помощью я все еще могу сохранить безопасность типов в будущем, не соглашаясь на конкретную реализацию (например, декодирование JSON).

// Protocols

protocol Query {
    associatedtype Result
    func handleResult(with data: Data) -> Result
}

protocol Setting {
    var name: String { get }
    var icon: URL? { get }
}

protocol LanguageSetting: Setting {
}

protocol CountrySetting: Setting {
}

// Implementations

struct LanguageSettingQuery: Query {
    func handleResult(with data: Data) -> [LanguageSetting] {
        return try! JSONDecoder().decode([JSONLanguageSetting].self, from: data)
    }
}

struct CountrySettingQuery: Query {
    func handleResult(with data: Data) -> [CountrySetting] {
        return try! JSONDecoder().decode([JSONCountrySetting].self, from: data)
    }
}

struct JSONLanguageSetting: LanguageSetting, Decodable {
    var name: String
    var icon: URL?
}

struct JSONCountrySetting: CountrySetting, Decodable {
    var name: String
    var icon: URL?
}

// A generic settings view controller
class LocaleViewController<LocaleQuery: Query>: UIViewController where
LocaleQuery.Result: Sequence, LocaleQuery.Result.Element: Setting {
    private var settingItems = [Setting]()

    init(query: LocaleQuery) {
        settingItems = query.handleResult(with: Data()) as! [Setting]
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

let localeVC = LocaleViewController(query: LanguageSettingQuery())

Выше приведеноочень простая реализация, которую я создал в Playgrounds.Проблема в том, что последняя строка:

let localeVC = LocaleViewController(query: LanguageSettingQuery())

выдает ошибку:

Использование «LanguageSetting» в качестве конкретного типа, соответствующего протоколу «Setting»не поддерживается

Любые идеи о том, как я мог бы обойти это?

С другой стороны:

Почему здесь необходим понижающий рейтинг?Разве общих ограничений типа не достаточно для обеспечения этого?

settingItems = query.handleResult(with: Data()) as! [Setting]
...