Я пытаюсь создать подкласс или расширить UIColor для поддержки нескольких протоколов.
Допустим, мой протокол выглядит следующим образом:
public protocol MyProtocol {
init(myValue: Any) throws
}
По какой-то причине я не могу реализовать его, и я не знаю почему.
Это работает для всех других классов:
class MyTestClass:SomeOtherClass, MyProtocol{
required init(myValue: Any) throws{
super.init(someOtherClassInitializer:Any)
}
}
Нет проблем. Но если я пытаюсь сделать это с помощью UIColor, я получаю ошибки.
class MyColor:UIColor, MyProtocol{
required init(myValue: Any) throws {
super.init(red: 0, green: 0, blue: 0, alpha: 1)
}
}
Прежде всего, он жалуется на required:Coder
-init. Хорошо, предоставьте это. fatalError в порядке. Затем он жалуется на другой иници. В нем говорится, что
'обязательный' инициализатор 'init (_colorLiteralRed: green: blue: alpha :)' должен быть предоставлен подклассом 'UIColor'
Weird flex, но Хорошо. Давайте добавим это тоже. Я нажимаю «Исправить», и он добавляет эту заглушку:
@nonobjc required convenience init(_colorLiteralRed red: Float, green: Float, blue: Float, alpha: Float) {
fatalError("init(_colorLiteralRed:green:blue:alpha:) has not been implemented")
}
Затем он дает мне две ошибки, одну идентичную той, на которую я только что нажал «Исправить» (которая добавляет другую идентичную инициализацию, и снова и еще раз), и другой, который говорит:
Переопределение non-@objc объявлений из расширений не поддерживается
Я не в расширении, но я предполагаю, что это удобный инициализатор возможно? Но тогда почему я должен реализовать - а также невозможно реализовать ?
Я знаю, «вы не должны подкласс UIColor», но я думаю, что я должен если я хочу, чтобы это сработало. Это странный запрос, поэтому некоторая справочная информация; Я использую библиотеку Apollo для выполнения сетевых задач GraphQL, которая использует скрипт для преобразования ожидаемого ответа в строго типизированные объекты swift, чтобы я мог использовать их в коде без десериализации их вручную. Он работает отлично.
Большинство значений являются стандартными и примитивными типами, такими как String, Int et c., Но иногда сервер пытается отправить мне объект класса, чуждого Swift, и по умолчанию они будут String
. Что совершенно нормально. Но я хочу больше фантазии. Пример; значение «2020-01-14T10: 00: 00» может быть возвращено как класс с именем DateTime
с сервера, но поскольку «DateTime» не существует ни в моем проекте, ни в Swift, автоматически созданные классы будут содержать их как String
-значение, и мне придется рассматривать его как строку.
Поскольку я хочу использовать эти автоматически сгенерированные классы вплоть до представления, это означает, что я должен преобразовать его из Строка для даты везде, где она используется. Другой вариант - создать свои собственные версии всех классов и преобразовать все иностранные классы в свои собственные, например, String-> Date, что скучно. Я хочу, чтобы это делалось автоматически для меня.
Хорошо, что Apollo позволяет мне создавать свои собственные скаляры. Так что с этим примером «DateTime -> Date» я могу просто сказать
typealias DateTime = Date
extension DateTime, JSONDecodable, JSONEncodable{ ... }
Это позволяет Аполлону знать, что есть соответствующий класс, в который могут быть преобразованы объекты класса «DateTime». И протоколы JSONDecodable и JSONEncodable рассказывают, как (что я сам реализую). Используя это, автоматически сгенерированный код будет сгенерирован так, что любое значение даты теперь будет DateTime (например, Date) вместо String. Хорошо!
Так что я подумал, почему бы не использовать это в наших интересах? Мы также получаем hex-цвета от этого API. Итак, мы сделали так, чтобы API возвращал шестнадцатеричный код ("#FFFFFF") как класс HexColorCode
. По умолчанию это просто превратится в String
, поэтому я должен инициализировать UIColor с помощью hex везде, где я хочу его использовать. Но сейчас я пытаюсь использовать тот же лог c, чтобы у автоматически сгенерированных классов был UIColor, который я могу использовать везде. Но вышесказанное происходит.
Я предполагаю, что Date, будучи public struct
из Foundation
, обладает некоторой свободой, которой не обладает UIColor, open class
из UIKit
, унаследованной от NSObject
, Но что и почему?
Я думаю, что возможно создать объект-оболочку, так что я могу сказать, что "HexColorCode" - это отдельный класс, который имеет одно поле color
, и Я бы сказал myView.backgroundColor = apiModel.color.color
вместо apiModel.color
. Но я действительно хотел, чтобы это сработало ..