相关疑难解决方法(0)

如何在Swift 4可解码协议中解码具有JSON字典类型的属性

假设我的Customer数据类型包含一个metadata属性,该属性可以包含客户对象中的任何JSON字典

struct Customer {
  let id: String
  let email: String
  let metadata: [String: Any]
}
Run Code Online (Sandbox Code Playgroud)
{  
  "object": "customer",
  "id": "4yq6txdpfadhbaqnwp3",
  "email": "john.doe@example.com",
  "metadata": {
    "link_id": "linked-id",
    "buy_count": 4
  }
}
Run Code Online (Sandbox Code Playgroud)

metadata属性可以是任意JSON映射对象.

在我NSJSONDeserialization使用新的Swift 4 Decodable协议从反序列化的JSON中转换属性之前,我仍然无法想到这样做的方法.

有人知道如何使用可解码协议在Swift 4中实现这一目标吗?

json swift swift4 codable

84
推荐指数
6
解决办法
5万
查看次数

Swift结构:为单个属性处理多种类型

我正在使用Swift 4并尝试解析一些JSON数据,这些数据显然在某些情况下可以为同一个键具有不同的类型值,例如:

{
    "type": 0.0
}
Run Code Online (Sandbox Code Playgroud)

{
    "type": "12.44591406"
}
Run Code Online (Sandbox Code Playgroud)

我实际上坚持定义我,struct因为我无法弄清楚如何处理这种情况,因为

struct ItemRaw: Codable {
    let parentType: String

    enum CodingKeys: String, CodingKey {
        case parentType = "type"
    }
}
Run Code Online (Sandbox Code Playgroud)

投掷"Expected to decode String but found a number instead.",当然,

struct ItemRaw: Codable {
    let parentType: Float

    enum CodingKeys: String, CodingKey {
        case parentType = "type"
    }
}
Run Code Online (Sandbox Code Playgroud)

因此投掷"Expected to decode Float but found a string/data instead.".

在定义我的时候如何处理这个(和类似的)情况struct呢?

json data-structures swift swift-structs swift4

7
推荐指数
2
解决办法
3256
查看次数

在Swift中动态解码任意json字段

TL; DR

有没有一种方法可以使用JSONDecoder并编写一个函数,它只是从给定的json读出指定的可解码类型的字段值?


成像我有以下json:

{
   "product":{
      "name":"PR1",
      "price":20
   },
   "employee":{
      "lastName":"Smith",
      "department":"IT",
      "manager":"Anderson"
   }
}
Run Code Online (Sandbox Code Playgroud)

我有2个Decodable结构:

struct Product: Decodable {
    var name: String
    var price: Int
}

struct Employee: Decodable {
    var lastName: String
    var department: String
    var manager: String
}
Run Code Online (Sandbox Code Playgroud)

我想写一个函数

func getValue<T:Decodable>(from json: Data, field: String) -> T { ... }
Run Code Online (Sandbox Code Playgroud)

所以我可以这样称呼它:

let product: Product = getValue(from: myJson, field: "product")
let employee: Employee = getValue(from: myJson, field: "employee")
Run Code Online (Sandbox Code Playgroud)

这是可能的,JSONDecoder或者我应该弄乱JSONSerialization,首先读出给定json的"子树",然后将其传递给解码器?在swift中似乎不允许在泛型函数中定义结构.

json nsjsonserialization swift jsondecoder

5
推荐指数
1
解决办法
478
查看次数

用Codable解码JSON时有没有?

使用Swift 3 JSONSerialization,如果您的数据模型的一部分是完全动态的,您可以随时保留反序列化数据,Any并让消费者处理它.

有了Swift 4 Codable,我想这样做:

struct Foo : Codable {
    let bar: Any;
}
Run Code Online (Sandbox Code Playgroud)

但我明白了

JSONPlayground.playground:4:9: note: cannot automatically synthesize 'Decodable' because 'Any' does not conform to 'Decodable'
    let bar: Any;
        ^
Run Code Online (Sandbox Code Playgroud)

如果我能够实现自己的那个,那就不会是世界末日Decodable,但这需要Decoder支持解码Any,据我所知,它不会.例如:

extension Foo {
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let result = try container.decode(AnyClass.self)
    }
}
Run Code Online (Sandbox Code Playgroud)

error: JSONPlayground.playground:4:36: error: cannot invoke 'decode' with an argument list of type '(AnyClass.Protocol)'
        let result …
Run Code Online (Sandbox Code Playgroud)

json swift swift4

3
推荐指数
2
解决办法
5482
查看次数

带有多维和多类型数组的 Swift 4 JSON 可解码

{
"values":[
[1,1,7,"Azuan Child","Anak Azuan","12345","ACTIVE","Morning",7,12,"2017-11-09 19:45:00"],
[28,1,0,"Azuan Child2","Amran","123456","ACTIVE","Evening",1,29,"2017-11-09 19:45:00"]
]
}
Run Code Online (Sandbox Code Playgroud)

好的,这是我从服务器收到的 json 格式

现在我想将它解码到我的结构中,但仍然没有运气。

struct ChildrenTable: Decodable {
    var values: [[String]]?
}
Run Code Online (Sandbox Code Playgroud)

我在 URLSession 上的调用者方法看起来像这样

URLSession.shared.dataTask(with: request) { (data, response, err) in
        guard let data = data else { return }

        let dataAsString = String(data: data, encoding: .utf8)
        print(dataAsString)

        do {
            let children  = try
                JSONDecoder().decode(ChildrenTable.self, from: data)
                print (children)
        } catch let jsonErr {
            print ("Error serializing json: ", jsonErr)
        }
    }.resume()
Run Code Online (Sandbox Code Playgroud)

我得到的错误是

Error serializing json:  
typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: …
Run Code Online (Sandbox Code Playgroud)

arrays json multidimensional-array swift4 decodable

2
推荐指数
1
解决办法
3188
查看次数

在 Swift 模型中解码数组(可解码)

我正在从 API 检索 JSON,并且想为我使用的每个端点创建一个模型。

\n\n

所有端点都使用以下格式:

\n\n
{\n  "id": "xxxxxx",\n  "result": {\xe2\x80\xa6},\n  "error": null\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

关键是:

\n\n
    \n
  • id始终是一个字符串
  • \n
  • error可以为或包含键的对象
  • \n
  • result可以为null;一个对象或一个数组。
  • \n
\n\n

我遇到的问题是,在端点之一上,结果是数组的数组:

\n\n
{\n  "id": "xxxxxx",\n  "result": [\n      [\n          "client_id",\n          "name",\n          50,\n          "status"\n      ]\n  ],\n  "error": null\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

正如您所看到的,我有数组的数组,其中值可以是字符串或整数。

\n\n

如何使用 Decodable 协议对其进行解码,然后根据其原始值将这些解码值用作 String 或 Int ?

\n

arrays swift decodable encodable

2
推荐指数
1
解决办法
1158
查看次数

Swift 4 Codable - Bool或String值

寻找一些关于如何处理我最近遇到的场景的输入.

我一直在使用Swift 4s Codable成功,但今天发现了一个我没想到的崩溃.我正在使用的API表示它返回了一个boolean密钥manage_stock.

我的存根结构看起来像:

struct Product: Codable {
    var manage_stock: Bool?
}
Run Code Online (Sandbox Code Playgroud)

这很好用,问题是API 有时会返回string而不是a boolean.

因此,我的解码失败了:

Expected to decode Bool but found a string/data instead.
Run Code Online (Sandbox Code Playgroud)

字符串只有等于"parent",我希望它等于false.

我也可以更改我的结构,var manage_stock: String?如果这样可以更容易地从API中获取JSON数据.但是,当然,如果我改变了,我的错误只会改为:

Expected to decode String but found a number instead.
Run Code Online (Sandbox Code Playgroud)

是否有一种简单的方法来处理这种突变,或者我是否需要丢失所有Codable带来的自动化并实现我自己的init(decoder: Decoder).

干杯

json swift codable

1
推荐指数
1
解决办法
4067
查看次数