微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 Swift HTTP POST 和解码 JSON 响应

如何解决使用 Swift HTTP POST 和解码 JSON 响应

根据之前的一些帮助,我能够构建此功能以从 swift 平台内提交 API POST 请求。

import Foundation

struct requestbody: Codable {
    let data: DataClass
}

// MARK: - DataClass
struct DataClass: Codable {
    let slices: [Slice]
    let passengers: [Passenger]
    let cabinClass: String

    enum CodingKeys: String,CodingKey {
        case slices,passengers
        case cabinClass = "cabin_class"
    }
}

// MARK: - Passenger
struct Passenger: Codable {
    let type: String
}

// MARK: - Slice
struct Slice: Codable {
    let origin,destination,departureDate: String

    enum CodingKeys: String,CodingKey {
        case origin,destination
        case departureDate = "departure_date"
    }
}
class APIPost {

func getposts(response: requestbody) -> URLRequest? {
        guard let url = URL(string: "https://api.duffel.com/air/offer_requests") else { return nil }
        var request = URLRequest(url: url)
        request.setValue("application/json",forHTTPHeaderField: "Content-Type")
        request.setValue("application/json",forHTTPHeaderField: "Accept")
        request.setValue("beta",forHTTPHeaderField: "Duffel-Version")
        request.setValue("Bearer [redacted]",forHTTPHeaderField: "Authorization")
        request.httpMethod = "POST"
        request.httpBody = try! JSONEncoder().encode(response)
        return request
}

然而,我会说,当谈到如何集成这个方法来解码 JSON 响应,然后在 UI 中使用时,我有点难受。我也无法在函数添加完成参数(添加 @escaping),并且相信最好采取此操作并在另一个函数中构建它。任何高级(或详细)的答复将不胜感激。

谢谢!

解决方法

使用此通用函数调用Post方法,调用此方法并在完成时传递请求体和响应体,并在其中添加URL

class func taskForPOSTRequest<RequestType: Encodable,ResponseType: Decodable>(url: URL,responseType: ResponseType.Type,body: RequestType,completion: @escaping (ResponseType?,Error?) -> Void) {
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.httpBody = try! JSONEncoder().encode(body)
        request.addValue("application/json",forHTTPHeaderField: "Content-Type")
        let task = URLSession.shared.dataTask(with: request) { data,response,error in
            guard let data = data else {
                DispatchQueue.main.async {
                    completion(nil,error)
                }
                return
            }
            let decoder = JSONDecoder()
            do {
                let responseObject = try decoder.decode(ResponseType.self,from: data)
                DispatchQueue.main.async {
                    completion(responseObject,nil)
                }
            } catch {
                print(error)
            }
        }
        task.resume()
    }
,

创建一个 URLRequest 实例是不够的,您还必须将此请求发送到您的服务器。您可以通过 URLSession API 发送。

// Notice the change in function signature
func getPost(requestBody: RequestBody,completion: @escaping ((_ posts: [Post]?,_ error: Error?) -> Void)) -> URLRequest? {
    
    // Everything else same up to this point
    request.httpBody = try! JSONEncoder().encode(requestBody)
    
    // Send the request to your server
    URLSession.shared.dataTask(with: request,completionHandler: { (data,urlResponse,error) in
       
        // Check if there was an error from network/server
        if let error = error {
            print(error.localizedDescription)
            // call completion with error from network/server
            completion(nil,error)
            return // return early because there was an error
        }
        
        // No error if we are,check for data
        if let data = data {
            do {
                // Try decoding your data to your model
                let posts = try JSONDecoder().decode([Post].self,from: data)
                // call completion with your models array,no error
                completion(posts,nil)
            }
            catch {
                // there's a decoding error,call completion with decoding error
                completion(nil,error)
            }
        }
    }).resume() // resuming a dataTask is essential,otherwise the call won't be sent to server
    
    return request
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。