Я хочу создать универсальный контроллер вида для страницы настроек.Прямо сейчас настройки исходят из 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]