В расширении. Я работал над этой проблемой и больше не могу ее проверять. Извиняюсь.

аюсь написать расширение, чтобы удовлетворить протокол в расширении, например, так:

extension UIColor: JSONRepresentable {
    convenience init?(json: Any) {
        guard let colourArray = json as? [CGFloat] else {
            print("json was not an array of CGFloats")
            return nil
        }

        self.init(red: colourArray[0],
                  green: colourArray[1],
                  blue: colourArray[2],
                  alpha: colourArray[3])
    }
}

Я получаю эту ошибку:Initializer requirement 'init(json:)' can only be satisfied by a required initializer in the definition of non-final class 'UIColor', Если я добавлюrequired Ключевое слово, я получаю эту ошибку'required' initializer must be declared directly in class 'UIColor' (not in an extension), Есть ли причина и есть ли способ обойти это?

Редактировать: Просто чтобы быть ясно, вот протокол

protocol JSONRepresentable {
    init?(json: Any)
}
 Sulthan02 окт. 2017 г., 12:06
@ DávidPásztor Это очень важная часть. При реализации инициализатора из протокола,required должен быть там.
 Dávid Pásztor02 окт. 2017 г., 11:58
Какую версию Swift вы используете, в Swift4 ваш код отлично компилируется для меня? Хотя я должен был удалитьJSONRepresentable соответствие, так как я тестирую на детской площадке, но это должно иметь значение
 Josh Paradroid02 окт. 2017 г., 12:05
Я также использую Swift4. Я только что уточнил требования протокола. Это имеет значение?
 Josh Paradroid02 окт. 2017 г., 12:09
Да, но когда я добавляю это, я получаю вторую ошибку:'required' initializer must be declared directly in class 'UIColor' (not in an extension), Извините, если это не было ясно в вопросе.
 Leo Dabus02 окт. 2017 г., 13:26
Почему бы вам не создатьstruct Color: Codableдобавить эти 4 свойства (красный, зеленый, синий и альфа) и просто добавить вычисляемое свойство, чтобы получить из него UIColor? Вместо того, чтобы инициализировать его из массива CGFloats, просто используйте словарьlet json = """ {"red": 1.0, "green": 0.0, "blue": 0.0, "alpha": 1.0} """

Ответы на вопрос(2)

struct Color: Codable {
    let red, green, blue, alpha: CGFloat
}

extension Color {
    var uiColor: UIColor { return UIColor(color: self) }
    var cgColor: CGColor { return uiColor.cgColor }
    var ciColor: CIColor { return CIColor(color: uiColor) }
    var data: Data { return try! JSONEncoder().encode(self) }
}

extension UIColor {
    convenience init(color: Color) {
        self.init(red: color.red, green: color.green, blue: color.blue, alpha: color.alpha)
    }
    var color: Color {
        let color = CIColor(color: self)
        return Color(red: color.red, green: color.green, blue: color.blue, alpha: color.alpha)
    }
}
extension Data {
    var string: String {
        return String(data: self, encoding: .utf8) ?? ""
    }
}

Тестирование игровой площадки

let json = """
{"red": 0.5, "green": 0.0, "blue": 0.0, "alpha": 1.0}
"""

if let color = try? JSONDecoder().decode(Color.self, from: Data(json.utf8)) {
    print(color)                  // "Color(red: 0.5, green: 0.0, blue: 0.0, alpha: 1.0)\n"
    print(color.uiColor)          // "UIExtendedSRGBColorSpace 0.5 0 0 1\n
    print(color.data)         // "40 bytes\n"
    print(color.data.string)  // "{"red":0.5,"alpha":1,"blue":0,"green":0}\n"
}

let redColor = UIColor.red.color
let jsonData = redColor.data.string  // "{"red":1,"alpha":1,"blue":0,"green":0}"

Если вам нужно работать с вашим массивом CGFloats, вы можете переопределить инициализаторы JSON Encoder и Decoder:

extension Color {
    public init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        red   = try container.decode(CGFloat.self)
        green = try container.decode(CGFloat.self)
        blue  = try container.decode(CGFloat.self)
        alpha = try container.decode(CGFloat.self)
    }
    public func encode(to encoder: Encoder) throws {
        var container = encoder.unkeyedContainer()
        try container.encode(red)
        try container.encode(green)
        try container.encode(blue)
        try container.encode(alpha)
    }
}

тестирование

let values: [CGFloat] = [0.5,0.0,0.0,1.0]
let jsonData = try JSONSerialization.data(withJSONObject: values) // 11 bytes
let json = jsonData.string   // "[0.5,0,0,1]"

do {
    let color = try JSONDecoder().decode(Color.self, from: jsonData)
    print(color)                  // "Color(red: 0.5, green: 0.0, blue: 0.0, alpha: 1.0)\n"
    print(color.uiColor)          // "UIExtendedSRGBColorSpace 0.5 0 0 1\n
    print(color.data)                                  // "11 bytes\n"
    print(color.data.string)                           // "[0.5,0,0,1]\n"
    let encodedData = try JSONEncoder().encode(color)  // 11 bytes
    print(encodedData == jsonData)                     // true
} catch {
    print(error)
}

м:

class YourClass: ParentClass {
required init() {}

}

 Josh Paradroid09 нояб. 2017 г., 11:34
В какой класс?UIColor это не мой класс.
 Josh Paradroid14 нояб. 2017 г., 13:56
В расширении. Я работал над этой проблемой и больше не могу ее проверять. Извиняюсь.
 Venu Gopal Tewari14 нояб. 2017 г., 07:30
@JoshParadroid Откуда вы получаете эту ошибку?

Ваш ответ на вопрос