我试图将我的swift结构转换为json格式。似乎有很多这样的问题,但到目前为止,没有一个解决方案对我有用。
这是我的结构
struct Rec : Codable {
var name:String
var time:Int
var values:[String]
var jsonRepresentation : String {
return """
{
"name":"\(name)",
"time":\(time),
"values":\(values)
}
"""
}
}
这是外部api接收的json格式。
{
"op" : "delete",
"rec": {
"name" : "some string",
"time":200,
"values": [
"127.0.0.1"
]
}
}
这是我的函数创建HTTP请求
private func createPatchRequest(op: String, url: URL, rec: Rec) throws -> URLRequest {
let dictionary: [String: String] = [
"op":op,
"rec":rec.jsonRepresentation
]
let jsonData = try JSONEncoder().encode(dictionary)
var request = URLRequest(url: url)
request.httpMethod = "PATCH"
request.httpBody = jsonData
request.addValue("application/json", forHTTPHeaderField:"Content-Type")
return request
}
我总是得到400,我相信swift不是'正确编码我的json。我试过邮递员的请求,它工作得很好!
这是邮差的看法
{
"op" : "delete",
"rec": {
"name" : "some string",
"time":600,
"values": [
"127.0.0.1"
]
}
}
有任何想法吗?谢谢!
问题是API期望rec
是一个JSON对象,但是你发送Rec作为JSON对象的字符串表示。即这是您要发送的JSON:
{
"rec": "{\n\"name\":\"some string\",\n\"time\":1,\n\"values\":[\"127.0.0.1\"]\n}",
"op": "delete"
}
理想的方法是使用嵌套的Codable
结构创建一个PatchRequest
Rec
并对其进行编码。您可以在Playground上尝试以下代码段
struct Rec : Codable {
var name:String
var time:Int
var values:[String]
}
struct PatchRequest : Codable{
var op: String
var rec: Rec
}
let rec = Rec(name: "some string",time: 600,values: ["127.0.0.1"])
let requst = PatchRequest(op: "delete",rec: rec)
let jsonData = try JSONEncoder().encode(requst)
let jsonString = String(data: jsonData, encoding: .utf8)
这样做的另一个好处是可以减少API方法所需的参数数量,并使代码整体更清晰:
private func createPatchRequest(url: URL, patchRequest: PatchReuest) throws -> URLRequest {
let jsonData = try JSONEncoder().encode(patchRequest)
var request = URLRequest(url: url)
request.httpMethod = "PATCH"
request.httpBody = jsonData
request.addValue("application/json", forHTTPHeaderField:"Content-Type")
return request
}
最后,我建议在你的结构中使用let
而不是var
,除非它是绝对必要的。
你的jsonRepresentation是一个字符串,但应该是一个字典。以这种方式更新您的结构:
struct Rec : Codable {
var name:String
var time:Int
var values:[String]
var jsonRepresentation: [String: Any] {
return [
"name": name,
"time": time,
"values": values
]
}
}
希望能帮助到你!如果有效,请告诉我。