首页 > 解决方案 > 如何使 UIFont 符合可解码

问题描述

我正在努力使其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

标签: iosswiftuikitdecodable

解决方案


我在手机上写,所以我不能尝试这个片段,但我认为这可以工作。让我知道它是否有帮助。

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)
}
}

推荐阅读