【问题标题】:Passing the contents of a text file as JSON to httpBody将文本文件的内容作为 JSON 传递给 httpBody
【发布时间】:2019-11-14 23:57:33
【问题描述】:

想通了,见下文:

我正在尝试创建一个可以将文本文件的内容快速传递给 http POST 请求的程序。我正在为我在文本文件中运行的 API 查询存储过滤器,并希望将它们作为 JSON 对象(?我认为,无论如何)传递给请求中的 request.httpBody。我在将 txt 文件转换为 httpBody 可以接受的数据(json 对象?)时遇到问题。

这里是一个示例 txt 文件。使用 OR 逻辑组合同一数组中的过滤器。过滤器数组使用 AND 逻辑组合,因此我必须考虑这两种情况。:

zero_RC.txt

{
    "query": "Zero Response Code",
    "filters": [
    {
        "filters": [
        {
            "field": "inventoryState",
            "value": "CONFIRMED",
            "type": "IN"
        },
        {
            "field": "responseCode",
            "value": "0",
            "type": "EQ"
        },
        {
            "field": "exception",
            "value": "DNS lookup failed",
            "type": "EQ"
        }]
    }]
}

这是我要开始工作的块。我相信我需要一个 JSON 对象,并且可以在下面的请求中将它传递给 httpBody。但是,仍然是这方面的初学者。

    // get JSON, somehow
    let file = Bundle.main.path(forResource: "zero_RC", ofType: "txt")
    let jsonData = file!.data(using: .utf8)

    let JSON = try! JSONSerialization.data(withJSONObject: jsonData as Any, options: [])

    if JSONSerialization.isValidJSONObject(JSON) {
        print("Oh Yeah")
    } else {
        print("Nah bud, that ain't working")
    }


    // make the request
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    request.addValue("Basic \(loginData!)", forHTTPHeaderField: "Authorization")
    request.httpBody = JSON

那么我是在获取一个字符串并转换为数据,然后再转换为 JSON 对象吗?我对如何最好地做到这一点感到非常困惑。我已经搜索和搜索,我发现的只是解析文章,这并没有帮助。

提前谢谢。


回答:

问题出在 request.setValue 中。我需要使用Content-Type 而不是Accept

    // get JSON
    let path = Bundle.main.path(forResource: "zero_RC", ofType: "txt")
    let data = try! Data(contentsOf: URL(fileURLWithPath: path!), options: .mappedIfSafe)


    // make the request
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("Basic \(loginData!)", forHTTPHeaderField: "Authorization")
    request.httpBody = data

【问题讨论】:

  • 你的文本文件中的数据已经序列化为JSON,无需再次序列化。只需将jsonData 直接分配给httpBody 属性即可。
  • 当我这样做request.httpBody = jsonData 时,我收到["errorMessage": , "errorCode": 415] 的错误
  • 这看起来像HTTP status code。 415 是“不支持的媒体类型”。尝试将application/json 设置为Content-Type 而不是Accept
  • 真棒@daltonclaybrook,就是这样。现在整理好了。我很快就会在这里更新答案。

标签: swift


【解决方案1】:

这是解决方案,首先我们将您的 json 文件解码为数据模型,然后将该数据模型对象编码为 httpBody。

let path = Bundle.main.path(forResource: "zero_RC", ofType: "txt")
let data = try! Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let jsonDecoder = JSONDecoder()
let json = try! jsonDecoder.decode(JsonObjModel.self, from: data)

//  now encoding that jsonData to the http body
let encoder  = JSONEncoder()
urlRequest.httpBody =  try! encoder.encode(json)

“JsonObjModel”将如下所示

// MARK: - JSONObjModel
struct JSONObjModel: Codable {
    let query: String
    let filters: [JSONObjModelFilter]
}

// MARK: - JSONObjModelFilter
struct JSONObjModelFilter: Codable {
    let filters: [FilterFilter]
}

// MARK: - FilterFilter
struct FilterFilter: Codable {
    let field, value, type: String
}

【讨论】:

  • 使用此代码;在let json = try! 我收到此错误(unknown context at $1098d9074).(unknown context at $1098d907c).JSONObjModel。知道为什么吗?此外,运行此代码时获得相同的["errorMessage": , "errorCode": 415]
  • 您确定上面提供的 json 是您文件中的实际值还是您遗漏了什么?
猜你喜欢
  • 1970-01-01
  • 2012-03-17
  • 1970-01-01
  • 2019-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
相关资源
最近更新 更多