将swift结构转换为json字符串

cx6n0qe3  于 2022-11-26  发布在  Swift
关注(0)|答案(2)|浏览(250)

我正在尝试将我的swift struct转换为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。我在postman上尝试了这个请求,它工作得很好!
这是它在 Postman 身上的样子

{
    "op" : "delete",
    "rec": { 
        "name" : "some string",
        "time":600,
        "values": [ 
            "127.0.0.1"
        ]
    }
}

有什么主意吗?谢谢!

ru9i0ody

ru9i0ody1#

问题是API期望rec是一个JSON对象,但是您发送的Rec是JSON对象的字符串表示。例如,您发送的JSON是:

{
  "rec": "{\n\"name\":\"some string\",\n\"time\":1,\n\"values\":[\"127.0.0.1\"]\n}",
  "op": "delete"
}

理想的方法是用嵌套的Rec结构体创建一个CodablePatchRequest并对其进行编码。

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 request = PatchRequest(op: "delete",rec: rec)

let jsonData = try JSONEncoder().encode(request)
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,除非绝对必要。

mtb9vblg

mtb9vblg2#

您的jsonRepresentation是一个字符串,但应该是一个字典。请按以下方式更新您的结构:

struct Rec : Codable {
var name:String
var time:Int
var values:[String]

var jsonRepresentation: [String: Any] {
    return [
        "name": name,
        "time": time,
        "values": values
    ]
  }
}

希望有帮助!如果起作用了请告诉我。

相关问题