'How to send an array of JSON object as a parameter value in request body ios swift

Hello I'm using Invoice generator api JSON Input https://invoice-generator.com/developers#json-input In the documentation of the API it is mentioned that the items key takes an array of json objects as value. enter image description here

Here is my swift dictionary representation of the body

let parameters: [String: Any] = [
        "from":"Invoiced, Inc.",
        "to": "Acme, Corp.",
        "logo":"https://invoiced.com/img/logo-invoice.png",
        "number":1,
        "items":["name":"starter plan",
                 "quantity":1,
                "unit_cost":99],
        "notes":"Thanks for your business!"
    ]

The problem is I get my invoice and display it in PDFView when I send an empty item array as

item:[]

But when I send with some values in the array I get invalid response from the server.

How can I send an array of JSON objects as a value for item key in the API request body



Solution 1:[1]

You need to encode an object to JSON. First, you should create the object:

struct JSONParameters {
    let from: String
    let to: String
    let logo: String
    let number: Int
    // ... all other parameters
}

Then, encode it to JSON and add it to the request body:

            do {
                let parameters = JSONParameters(from: "Invoiced Inc.", to:......)   // Complete object
                let json = try JSONEncoder().encode(parameters)
                print("Encoded JSON: \(String(data: json, encoding: .utf8)!)")

                var request = URLRequest(url: yourURLHere)
                request.httpBody = json

                let (data, response) = try await URLSession.shared.data(for: request) // Or whatever function you need to use

                // Manage response

            } catch {
                print("\n-->> Error trying to encode : \(error) - \(String(describing: parameters))")
            }

Solution 2:[2]

OUTPUT: -

[
    "number": 1,
    "to": "Acme, Corp.",
    "notes": "Thanks for your business!",
    "from": "Invoiced, Inc.",
    "logo": "https://invoiced.com/img/logo-invoice.png",
    "items": [
        ["quantity": 1, "name": "Starter plan", "unit_cost": 99],
        ["quantity": 1, "name": "Starter plan2", "unit_cost": 99]
    ]
]
struct BodyModel: Codable {
    var from, to: String?
    var logo: String?
    var number: Int?
    var items: [Item]?
    var notes: String?
    
    func toDict() -> [String:Any] {
        var dictionary = [String:Any]()
        if from != nil {
            dictionary["from"] = from
        }
        if to != nil {
            dictionary["to"] = to
        }
        if logo != nil {
            dictionary["logo"] = logo
        }
        if number != nil {
            dictionary["number"] = number
        }
        if items != nil {
            var arrOfDict = [[String:Any]]()
            for item in items! {
                arrOfDict.append(item.toDict())
            }
            dictionary["items"] = arrOfDict
        }
        if notes != nil {
            dictionary["notes"] = notes
        }
        return dictionary
    }
}
struct Item: Codable {
    var name: String?
    var quantity, unit_cost: Int?
    
    func toDict() -> [String:Any] {
        var dictionary = [String:Any]()
        if name != nil {
            dictionary["name"] = name
        }
        if quantity != nil {
            dictionary["quantity"] = quantity
        }
        if unit_cost != nil {
            dictionary["unit_cost"] = unit_cost
        }
        return dictionary
    }
}
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        var arrItems = [Item]()
        arrItems.append(Item(name: "Starter plan", quantity: 1, unit_cost: 99))
        arrItems.append(Item(name: "Starter plan2", quantity: 1, unit_cost: 99))
        
        let body = BodyModel(from: "Invoiced, Inc.",
                             to: "Acme, Corp.",
                             logo: "https://invoiced.com/img/logo-invoice.png",
                             number: 1,
                             items: arrItems,
                             notes: "Thanks for your business!")
        
        let parameters: [String: Any]  = body.toDict()
        print(parameters)
        
    }
}

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 HunterLion
Solution 2 Milan Savaliya M