如何使UIFont符合可解码

时间:2019-05-29 13:27:12

标签: ios swift uikit decodable

我正在尝试使UIFont符合Decodable,但是我很难过。

我目前有一种解决方案,可以将UIFont包装在这样的Font结构中

public struct Font: Decodable{
    let font: UIFont

    private enum CodingKeys: String, CodingKey {
        case size
        case font
    }

    public init(from decoder: Decoder){
        do{
            let values = try decoder.container(keyedBy: CodingKeys.self)
            font = UIFont(name: try values.decode(String.self, forKey: .font), size: try values.decode(CGFloat.self, forKey: .size))!
        } catch{
            fatalError("Font configuration error:\(error)")
        }
    }
}

这可行,但是我看起来笨拙,所以我尝试这样:

final class Font: UIFont, Decodable{
    private enum CodingKeys: String, CodingKey {
        case size
        case font
    }

    convenience init(from decoder: Decoder)  {
        do{
            let values = try decoder.container(keyedBy: CodingKeys.self)
            super.init(name: try values.decode(String.self, forKey: .font), size: try values.decode(CGFloat.self, forKey: .size))
        } catch{
            fatalError("Font configuration error:\(error)")
        }
    }
}

但是这不起作用,因为init(from decoder: Decoder)不能是可失败的初始化,而UIFont.init(name: String, size: CGFloat)是可失败的初始化,并且不可能从不可失败的初始化中调用可失败的初始化。

任何建议如何使UIFont符合Decodable而不包装它的建议,都受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

我正在写手机,所以我无法尝试此代码段,但我认为这可以工作。让我知道是否有帮助。

final class Font: Codable {
let size: CGFloat
let name: String

var font: UIFont = UIFont.init()

init(s: CGFloat, n: String) {
    size = s
    name = n

    font = UIFont(name: name, size: size) ?? UIFont.systemFont(ofSize: size)
}

enum CodingKeys: String, CodingKey {
    case size
    case name
}

required init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)

    size = try container.decode(CGFloat.self, forKey: .size)
    name = try container.decode(String.self, forKey: .name)

    font = UIFont(name: name, size: size) ?? UIFont.systemFont(ofSize: size)
}

func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)

    try container.encode(size, forKey: .size)
    try container.encode(name, forKey: .name)
}
}