V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
BeyondBouds
V2EX  ›  Swift

请大佬指教 Swift codable 的问题

  •  
  •   BeyondBouds · 2022-11-04 11:08:31 +08:00 · 1054 次点击
    这是一个创建于 748 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我刚用 swift

    用到 codable 时,有两个疑问

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

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

    你可以自己定义需要 encode/decode 哪些字段,或者实现方法决定怎么 encode/decode 它
    xtinput
        3
    xtinput  
       2022-11-04 13:22:34 +08:00
    codable 可以自定义字段的呀
    chiaf
        4
    chiaf  
       2022-11-04 13:29:59 +08:00
    上第三方库吧

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

    推荐 SwiftyJSON
    cssk
        5
    cssk  
       2022-11-04 13:34:25 +08:00 via iPhone
    如果数据量不大,不在乎效率,那就上 swiftyjson 吧
    BeyondBouds
        6
    BeyondBouds  
    OP
       2022-11-04 14:07:35 +08:00
    @hstdt
    @pocarisweat
    @xtinput
    @chiaf
    @cssk
    非常感谢各位的回复。
    因为不知道其他端的字段 嵌套层级是怎么样的,里面有什么字段,字段的值又是类型的...所以没法介入 codable 的过程...
    由于已经开发了大部分了,感觉换 swiftJson 成本有点高,我先找找其他解决办法吧...
    foxwe10
        7
    foxwe10  
       2022-11-07 01:08:25 +08:00
    1. 针对后端返回的数据,不太确定你的需求是什么样子。假如返回的数据中你需要的字段是 json 数据结构对应的子集,可以定义实现 Decodable 协议的 struct/class 只有你需要的字段作为 Codingkey ,不需要转换为 json 再转换为 Data
    2. SwiftyJson 是支持 Codable 的,如果觉得性能有问题,他的 repo 中有一个优化过的 pr ,可以参考,本身 SwiftyJson 只有一个文件,比较好处理。
    foxwe10
        8
    foxwe10  
       2022-11-07 01:11:38 +08:00
    @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
    }
    }
    ```
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2866 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 14:51 · PVG 22:51 · LAX 06:51 · JFK 09:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.