无法快速发出发布请求

时间:2018-11-19 06:38:55

标签: json swift post

无法处理POST请求,但无法理解原因,该结构是可编码的,并且url中没有错误。我在控制台中收到此消息错误

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write'
*** First throw call stack:
(0x1ac0dfea0 )
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

但是一切似乎都没问题

我的结构:

struct PostOfMine: Codable {
    let body: String?
    let id: Int?
    let title: String?
    let userId: Int?
}

我的功能:

func postData() {
    guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts") else {
        print("WARNING: url related error")
        return}
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.addValue("Application/json", forHTTPHeaderField: "Content-Type")

    let newPost = PostOfMine(body: "test body", id: 20, title: "test title", userId: 20)

    do {
        let jsonBody = try JSONSerialization.data(withJSONObject: newPost, options: [])
        request.httpBody = jsonBody
    } catch {
        print(error.localizedDescription)
    }

let session = URLSession.shared
let task = session.dataTask(with: request) { (Data, _, error) in
    guard let data =  Data else {return}
    do {
        let sentPost = try JSONSerialization.jsonObject(with: data, options: [])
        print(sentPost)
    } catch {
        print(error.localizedDescription)
    }
}
task.resume()

}

2 个答案:

答案 0 :(得分:0)

由于您的模型符合Codable,因此您可以免费获得JSONEncoder().encode(_:)。用它代替JSONSerialization

进行编码
func postData() {

//...

//For this particular api, the server will take care of generating an `id` so leave that as `nil`

  let newPost = PostOfMine(body: "test body", id: nil, title: "test title", userId: 20)

    do { 
    let jsonBody = try JSONEncoder().encode(newPost)

    } catch {
    print(error.localizedDescription)
    }

let session = URLSession.shared
session.dataTask(with: request) { _, response, error in 

if error != nil { 
//check & handle error from upload task. 
} 

if let response = response as? HTTPURLResponse {

 // Monitor the status code recieved from the server. 200-300 = OK
    print(response.statusCode)
 // prints 201 - Created

      }
  }.resume()

}

答案 1 :(得分:0)

根据苹果文件:

JSONSerialization.data(withJSONObject:obj,选项:[])

如果obj不会产生有效的JSON,则会引发异常。在解析之前抛出此异常,它表示编程错误,而不是内部错误。在使用isValidJSONObject(_ :)调用此方法之前,应检查输入是否会生成有效的JSON。

由于以下原因引发了代码异常

  1. JSONSerialization.data(withJSONObject:obj,选项:[]) 在此方法中,您必须传递有效的JSON对象,例如obj。您只需要确认 codable协议,然后传递结构变量而不是JSON对象即可。

代码:

struct PostOfMine: Codable {
    let body: String?
    let id: Int?
    let title: String?
    let userId: Int?

   private enum CodingKeys: String, CodingKey {
        case body
        case id
        case title
        case userId
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(body, forKey: .body)
        try container.encode(id, forKey: .id)
        try container.encode(title, forKey: .title)
        try container.encode(userId, forKey: .userId)
    }
}


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    let newPost = PostOfMine(body: "test body", id: 20, title: "test title", userId: 20)
    do {
        let encoder = JSONEncoder()
        let newPostData = try encoder.encode(newPost)
       //Send newPostData to your server.
        request.httpBody = newPostData
//Send data you your server


        //For Decoding the data use JSONDecoder
        let post = try JSONDecoder().decode(PostOfMine.self, from: newPostData)
        debugPrint(post)
    } catch {
        debugPrint(error.localizedDescription)
    }
}