V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
ShowYourPrompt
V2EX  ›  Swift

请大佬指教 Swift codable 的问题

  •  
  •   ShowYourPrompt · Nov 4, 2022 · 1842 views
    This topic created in 1281 days ago, the information mentioned may be changed or developed.
    我刚用 swift

    用到 codable 时,有两个疑问

    1.后端返回的数据我只用到一部分,我的做法是先转成 json ,然后取出我用到的字段的值,再转成 Data ,最后用 codable 转成我自己的 struct ,这就损失了效率,有好的解决办法嘛?

    2.我和其他端( web ,andriod ,后端)共同读写一份 json 文件,有共用的字段,也有各端单独用到的字段,不能在读写过程中弄丢了。我在用 codable 时,碰到其他端的字段,是[String : Any]或者[[String : Any]]类型的, 没法 Codable 了,这个怎么搞?
    8 replies    2022-11-07 01:11:38 +08:00
    hstdt
        1
    hstdt  
       Nov 4, 2022 via iPhone
    遇到第二个问题的场景,我会用这个库来解 https://github.com/SwiftyJSON/SwiftyJSON
    同时也满足 1 里面你想要的使用习惯
    pocarisweat
        2
    pocarisweat  
       Nov 4, 2022
    http://swiftcafe.io/post/codable

    你可以自己定义需要 encode/decode 哪些字段,或者实现方法决定怎么 encode/decode 它
    xtinput
        3
    xtinput  
       Nov 4, 2022
    codable 可以自定义字段的呀
    usVexMownCzar
        4
    usVexMownCzar  
       Nov 4, 2022
    上第三方库吧

    以前觉得 codable 牛逼,后来跟后端 API 对接的时候把我干懵了,一个 status_code 两种状态类型,Int 是一个状态,string 是另一种状态🙃

    推荐 SwiftyJSON
    cssk
        5
    cssk  
       Nov 4, 2022 via iPhone
    如果数据量不大,不在乎效率,那就上 swiftyjson 吧
    ShowYourPrompt
        6
    ShowYourPrompt  
    OP
       Nov 4, 2022
    @hstdt
    @pocarisweat
    @xtinput
    @chiaf
    @cssk
    非常感谢各位的回复。
    因为不知道其他端的字段 嵌套层级是怎么样的,里面有什么字段,字段的值又是类型的...所以没法介入 codable 的过程...
    由于已经开发了大部分了,感觉换 swiftJson 成本有点高,我先找找其他解决办法吧...
    foxwe10
        7
    foxwe10  
       Nov 7, 2022
    1. 针对后端返回的数据,不太确定你的需求是什么样子。假如返回的数据中你需要的字段是 json 数据结构对应的子集,可以定义实现 Decodable 协议的 struct/class 只有你需要的字段作为 Codingkey ,不需要转换为 json 再转换为 Data
    2. SwiftyJson 是支持 Codable 的,如果觉得性能有问题,他的 repo 中有一个优化过的 pr ,可以参考,本身 SwiftyJson 只有一个文件,比较好处理。
    foxwe10
        8
    foxwe10  
       Nov 7, 2022
    @chiaf 这种 Codable 也可以解决, 但实际上是后端的问题
    ```swift
    public enum EitherOr<T, V>: Codable where T: Codable, V: Codable {
    case either(T)
    case or(V)

    public init(from decoder: Decoder) throws {
    let container = try decoder.singleValueContainer()

    if let value = try? container.decode(T.self) {
    self = .either(value)
    } else if let value = try? container.decode(V.self) {
    self = .or(value)
    } else {
    throw DecodeError.unkownType
    }
    }

    public func encode(to encoder: Encoder) throws {
    var container = encoder.singleValueContainer()
    switch self {
    case let .or(value): try container.encode(value)
    case let .either(value): try container.encode(value)
    }
    }

    public var either: T? {
    switch self {
    case let .either(v): return v
    default: return nil
    }
    }
    public enum DecodeError: Error {
    case unkownType
    }
    }
    ```
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1250 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 43ms · UTC 17:37 · PVG 01:37 · LAX 10:37 · JFK 13:37
    ♥ Do have faith in what you're doing.