skip to Main Content

From some previous help, I was able to build out this to submit an API POST request from within the swift platform.

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
}

I will, however, say I am somewhat stumped when it comes to how to integrate this method to then decode the JSON response, to then use in a UI. I cannot add a completion parameter in the function (to add @escaping) either, and believe maybe it would be best to take this action and build off it in another function. Any high level (or detailed) responses would be greatly greatly appreciated.

Thank you!

2

Answers


  1. Use This generic function for calling Post Method,Call this method and pass request body and response body in completion , also add URL in same

    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()
        }
    
    Login or Signup to reply.
  2. Creating a URLRequest instance is not enough, you have to send this request to your server as well. You can send it via 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
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search