【问题标题】:Construct JSON within swift在 swift 中构造 JSON
【发布时间】:2022-01-22 22:43:09
【问题描述】:

我正在尝试使用 Swift 构建以下 JSON,因为这在我使用 Postman 进行测试时有效。我需要能够更改参数的值,所以我尽量避免只构建一个字符串:

{
   "item": {
      "record": "10",
      "field_name": "orientation_forward",
      "redcap_repeat_instance": "1",
      "redcap_repeat_instrument": "range_of_motion_result",
      "value": "4",
      "redcap_event_name": []
   }
}

这是我的尝试,但当我测试它时,它甚至似乎不是有效的 JSON:

var record = "10"
var field_name = "orientation_forward"
var repeat_instance = "1"
var repeat_instrument = "range_of_motion_result"
var value = "4"
var event: [String] = [] // not sure how else to pass in '[]' when empty

    let dataObject: [String: Any] = [
        "item":
            ["record": record,
             "field_name": field_name,
             "redcap_repeat_instance": repeat_instance,
             "redcap_repeat_instrument": repeat_instrument,
             "value": value,
             "redcap_event_name": event]
    ]
            
    if let jsonData = try? JSONSerialization.data(withJSONObject: dataObject, options: .init(rawValue: 0)) as? Data
    {
        // Check if it worked...
        print(String(data: jsonData!, encoding: .utf8)!)
        let jsonTest = JSONSerialization.isValidJSONObject(jsonData) // false!
        print(jsonTest)

    }

所有帮助都慷慨地接受了。提前致谢。

【问题讨论】:

  • 也许您应该先修复最明显的错误,然后再发布正确拼写变量名称之类的问题,确保您有匹配的 [ 和 ] 而不是随机使用!
  • 抱歉 - 复制/粘贴错误。

标签: json swift key-value redcap


【解决方案1】:

最好的方法是在这里使用Codable,开始时需要做更多的工作,但最终代码会更简洁。

所以首先我们创建一个符合Codable的结构体

struct Item: Codable {
    let record: String
    let fieldName: String
    let repeatInstance: String
    let repeatInstrument: String
    let value: String
    let event: [String]

    enum CodingKeys: String, CodingKey {
        case record
        case fieldName = "field_name"
        case repeatInstance = "redcap_repeat_instance"
        case repeatInstrument = "redcap_repeat_instrument"
        case value
        case event = "redcap_event_name"
    }
}

CodingKeys 枚举用于获取正确的字段名称

然后就这样使用

let item = Item(record: "10", fieldName: "orientation_forward", repeatInstance: "1", repeatInstrument: "range_of_motion_result", value: "4", event: [])

do {
    let data = try JSONEncoder().encode(["item": item])
    
    if let s = String(data: data, encoding: .utf8) { print(s) }
} catch {
    print(error)
}

{"item":{"field_name":"orientation_forward","value":"4","re​​dcap_event_name":[],"redcap_repeat_instrument":"range_of_motion_result","re​​cord":"10","re​​dcap_repeat_instance ":"1"}}

有些人更喜欢一直使用自定义类型,如果是这样,您可以创建顶级结构而不是使用字典

struct ItemContainer: Codable {
    let item: Item
}

然后编码会变成类似

let data = try JSONEncoder().encode(ItemContainer(item: item))

但最终结果是一样的

【讨论】:

  • 我明白了!非常感谢。这比我要去的地方优雅得多。在数据结构中看到枚举很有趣——我以前没见过。另外,如果我需要更改值,我假设我只是用变量替换“item”常量中的值?
  • 是的,您创建一个新的 Item 对象,其中包含每次您想要编码(并发送)时所需的值
  • 非常感谢!!
  • 嗯 - 奇怪的是,我得到 JSONSerialization.isValidJSONObject(data) 评估为假
  • 如果您的编码代码工作正常并且不会引发错误,则无关紧要
猜你喜欢
  • 1970-01-01
  • 2013-08-20
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多