如何以编码结构发布数据?

Posted

技术标签:

【中文标题】如何以编码结构发布数据?【英文标题】:How to post the data in encoding structure? 【发布时间】:2018-05-21 08:03:18 【问题描述】:

我使用了两种可编码和可解码的 GET 和 POST 模型

使用下面的代码,我能够在 GET 模型中获取数据,但我无法使用 POST 模型发布数据。

请指导我如何使用 POST 模型发布数据

let url = URL(string: "<YOUR URL HERE>")
let config = URLSessionConfiguration.default
config.httpAdditionalHeaders = [
"Accept" : "application/json",
"Content-Type" : "application/x-www-form-urlencoded"
]

let session = URLSession(configuration: config)

var request = URLRequest(url: url!)
request.encodeParameters(parameters: ["username": username, "password": 
password])

let task = session.dataTask(with: request)  data, response, error in
guard let data = data else  return 
  do 
      let sentPost = try JSONDecoder().decode(Get.self, from: data)
      print(sentPost)
   catch 

task.resume()

型号

struct Post: Encodable, Decodable 
    let username: String
    let password: String

URLRequest 的扩展

extension URLRequest 

private func percentEscapeString(_ string: String) -> String 
    var characterSet = CharacterSet.alphanumerics
    characterSet.insert(charactersIn: "-._* ")

    return string
        .addingPercentEncoding(withAllowedCharacters: characterSet)!
        .replacingOccurrences(of: " ", with: "+")
        .replacingOccurrences(of: " ", with: "+", options: [], range: nil)


mutating func encodeParameters(parameters: [String : String]) 
    httpMethod = "POST"

    let parameterArray = parameters.map  (arg) -> String in
        let (key, value) = arg
        return "\(key)=\(self.percentEscapeString(value))"
    

    httpBody = parameterArray.joined(separator: "&").data(using: String.Encoding.utf8)
  

【问题讨论】:

你的模特在哪里? 能否请您清理问题中的代码,即正确缩进并构造它。看起来它由一个类和一个单独的代码片段组成。如果是这样,让它显而易见。如果您希望得到其他人的帮助,请不要让他们不必要地难以理解问题和代码。 不要创建 & 分隔的字符串,而是尝试将整个字典作为数据发布。如果你在服务器端调试,你能看到正在发送的任何数据吗? @Codo,我已经清理了代码,请你现在帮忙 【参考方案1】:

您不需要创建另一个字符串,然后再创建数据。这将由Codable 协议和您的JSONEncoder 处理。您需要使用JSONEncoder 对您的帖子类型进行编码,并将数据提供给request.httpBody

试试这个:

let url = URL(string: "<YOUR URL HERE>")
let config = URLSessionConfiguration.default
config.httpAdditionalHeaders = [
    "Accept" : "application/json",
    "Content-Type" : "application/x-www-form-urlencoded"
]

do 
    let aPost = Post(username: "username", password: "password")
    let encoder = JSONEncoder()
    let encodedPost = try encoder.encode(aPost)

    let session = URLSession(configuration: config)
    var request = URLRequest(url: url!)
    request.httpMethod = "POST"
    request.httpBody = encodedPost

    let task = session.dataTask(with: request)  data, response, error in
        do 
            let sentPost = try JSONDecoder().decode(Get.self, from: data)
            print(sentPost)
         catch  
            print(error.localizedDescription)
        
    
    task.resume()
 catch 
    print(error.localizedDescription)

【讨论】:

感谢您的帮助@nayem,在使用上面的代码后,我收到错误 “无法读取数据,因为它丢失了。” 然后是其他问题。在 dataTask.. 函数的完成处理程序中放置一个断点并调查问题。也许您的解码不正确或者您的服务器没有向您发送数据 当然让我尝试一下,但我之前正在获取数据,如果我不使用您的代码,我仍然会获取数据,只是我无法使用 Post 模型和我的 是的,调查一下。您可以尝试print(String(data: data, encoding: .utf8) 来查看 API 实际返回的内容。 Optional("\"error\":\"unsupported_grant_type\"") 是错误,因为我发布的是 application/x-www-form-urlencoded 而不是 JSON

以上是关于如何以编码结构发布数据?的主要内容,如果未能解决你的问题,请参考以下文章

编码数据以进行插补,然后解码

如何将此数据编码为 JSON 中的父/子结构

即使在数据关闭后,我如何编码以保留数据?

如何编码以检查数组相交的数据?

如何以正确的方式编码和解码字符[重复]

如何发布具有多部分/表单数据编码的数组?