Search code examples
iosswiftresponse

iOS Swift 5 API Response isn't JSON, it has semicolons?


I am trying to work with an api response which comes back nicely in postman but when I print it in swift, it has semicolons at the end of lines

I have tried options and various ways of altering the request and handling of the response to no avail. Why are the semicolons there?

******* Code snippet ******

let todosEndpoint: String = "https://url:3000/api/v1/somestring? 
query=$filter%3DUPC%20eq%20'somenumber'"
    guard let todosURL = URL(string: todosEndpoint) else {
        print("Error: cannot create URL")
        return
    }
    var todosUrlRequest = URLRequest(url: todosURL)
todosUrlRequest.httpMethod = "GET"

todosUrlRequest.setValue("application/json", forHTTPHeaderField: 
"Content-Type")

todosUrlRequest.setValue("Bearer "+token, forHTTPHeaderField: "Authorization")


let task = URLSession.shared.dataTask(with: todosUrlRequest) { (data, response, error) in
guard let dataResponse = data,
    error == nil else {
        print(error?.localizedDescription ?? "Response Error")
    return }

    do{
        let myJson = try JSONSerialization.jsonObject(with: data!) as? NSDictionary

        print(myJson!)

******** Results *****

Desired Results:
{
"@odata.context": "https://api.url.com/v1/$metadata#Products",
"value": [
    {
        "ASIN": null,
        "Height": null,
        "Length": null,
        "Width": null,
        "Weight": null,
        "Cost": null,
        "Margin": null,
        "RetailPrice": null,
        "StartingPrice": null,
        "ReservePrice": null,
         }
    ]
}


Actual Results:
{
"@odata.context" = "https://api.url.com/v1/$metadata#Products";
value =     (
            {
        ASIN = "<null>";
        BlockComment = "<null>";
        BlockedDateUtc = "<null>";
        Brand = BAZZILL;
        BundleType = None;
        BuyItNowPrice = "0.99";
        CategoryCode = "<null>";
        CategoryPath = "<null>";
        Classification = "<null>";
        Condition = "<null>";
        Cost = "<null>";
        }
    );
}

Solution

  • If you are serializing the JSON as a dictionary which you are because you're doing:

    let myJson = try JSONSerialization.jsonObject(with: data!) as? NSDictionary
    print(myJson!)
    

    That means you access each field like: let comment = myJson["BlockComment"]

    However, it might be better to serialize as a structure:

    struct Product: Codable {
        let asin: String?
        let blockComment: String?
        let brand: String?
        let buyItNowPrice: Float?
        let cost: Float?
    
        enum CodingKeys: String, CodingKey {
            case asin = "ASIN"
            case blockComment = "BlockComment"
            case brand = "Brand"
            case buyItNowPrice = "BuyItNowPrice"
            case cost = "Cost"
        }
    }
    

    then you'd do:

    let product = try JSONDecoder().decode(Product.self)
    print(product.cost)
    print(product.brand)
    //etc..
    

    https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types

    https://developer.apple.com/documentation/foundation/archives_and_serialization/using_json_with_custom_types