在 swift 内构建 JSON
Construct JSON within swift
我正在尝试使用 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)
}
所有的帮助都被慷慨地接受了。提前致谢。
最好的方法是在此处使用 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","redcap_event_name":[],"redcap_repeat_instrument":"range_of_motion_result","record":"10","redcap_repeat_instance":"1"}}
有些人更喜欢一直使用自定义类型,如果是这样,您可以创建顶级结构而不是使用字典
struct ItemContainer: Codable {
let item: Item
}
然后编码会变成类似
let data = try JSONEncoder().encode(ItemContainer(item: item))
但最终结果是一样的
我正在尝试使用 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)
}
所有的帮助都被慷慨地接受了。提前致谢。
最好的方法是在此处使用 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","redcap_event_name":[],"redcap_repeat_instrument":"range_of_motion_result","record":"10","redcap_repeat_instance":"1"}}
有些人更喜欢一直使用自定义类型,如果是这样,您可以创建顶级结构而不是使用字典
struct ItemContainer: Codable {
let item: Item
}
然后编码会变成类似
let data = try JSONEncoder().encode(ItemContainer(item: item))
但最终结果是一样的