2

Hello I am beginner and trying to understand how to send an array with objects. Does the server understand what an array is like Int, Strings or Booleans? Do you have to send the array in a string for JSON? What I do not understand?

var productsResult = ""
let encoder = JSONEncoder()
let productObject = ProductUsed(name: "Custom name", reason: "This Reason", apply_way: "Intravenous infusion", dosing: "2x", date_start: "22-02-1999", date_end: "22-03-2003")
        
        do {
            let result = try encoder.encode([productObject])
            if let resultString = String(data: result, encoding: .utf8) {
                print(resultString)
                productsResult = resultString
            }
        } catch {
            print(error)
        }
        
json["products_used"] = productsResult

And I sent to server with parameters like this:

parameters:  ["pregnancy_week": 0, "body_height": 198, "initials": "John Appleseed", "heavy_effect": false, "sex": "Male", "pregnancy": false, "month_of_birth": 3, "reaction": "No option checked", "additional_info": "Eeee", "products_used": "[{\"date_end\":\"22-03-2003\",\"dosing\":\"2x\",\"date_start\":\"22-02-1999\",\"apply_way\":\"Intravenous infusion\",\"name\":\"Custom name\",\"reason\":\"This Reason\"}]", "description": "Eeee", "result": "Recovery without lasting consequences", "year_of_birth": 1983, "day_of_birth": 11, "issue_date": "15-11-2020", "body_weight": 78]

but printed "resultString" in log and looks good...

[{"date_end":"22-03-2003","dosing":"2x","date_start":"22-02-1999","apply_way":"Intravenous infusion","name":"Custom name","reason":"This Reason"}]

What's wrong in my code and why I have " \ " between words in "products_used" key?

handzel
  • 91
  • 1
  • 10
  • 1
    Because you do `json["products_used"] = productsResult`, so you are setting a String, so it's JSON stringified that you get. `json` can't be a Codable too? – Larme Nov 15 '20 at 18:22
  • @Larme You're right. How do I pass a value to this parameter? – handzel Nov 15 '20 at 18:24
  • Why don't you have `struct SomenameThatMakeSense { let pregnancyWeek: Int; bodyHeight: Int; initials: String; ... let productsUsed = [ProductUsed]; ...}`? – Larme Nov 15 '20 at 18:26
  • @Larme I have struct, I did just like there: [link](https://stackoverflow.com/questions/51121051/how-to-send-an-array-of-objects-to-server-in-swift) – handzel Nov 15 '20 at 18:46
  • @Larme When I sent Array with objects from my Api method without JSONEncoder() the parameter look like: `"products_used": [testApp.ProductUsed(name: "Example", reason: "Some Test", apply_way: "Hmm Test", dosing: "Testable", date_start: "22-02-1998", date_end: "27-12-2010")],` – handzel Nov 15 '20 at 18:57
  • I meant: `json["products_used"]`, what's the variable `json` in your case? I guess that's the `Dictionary`? Well why not it be a `struct`? How is it defined? How do you use it? Your issue comes from the the fact that you have Stringified JSON within JSON. – Larme Nov 15 '20 at 22:01
  • `static func reportSideEffect(initials: String?, gender: String?, bodyHeight: Int?, bodyWeight: Int?, yearOfBirth: Int?, monthOfBirth: Int?, dayOfBirth: Int?, dateOfIssue: String?, description: String?, result: String?, pregnancy: Bool?, pregnancyWeek: Int?, heavyEffect: Bool?, reaction: String?, productsUsed: [ProductUsed]?, additionalInfo: String?, withSuccess success: @escaping (Bool) -> Void) { guard let url = URL(string: ApiEndpoint.SideEffect.reportSideEffect) else { success(false) return } ` and `var json = [String: Any]()` – handzel Nov 15 '20 at 22:47
  • Again, why use `json = [String: Any]()`, and not a custom `struct`? You are parsing it twice.And what do you do with `json` later? You use JSONSerilization? Avoid mixing JSONSerialization AND Codable. Use one of them (prefers Codable), not both. – Larme Nov 15 '20 at 22:54

1 Answers1

1

JSON, unlike XML, does not specify the structure and type explicitly. This means that the server must know what JSON data to expect.

In JSON there are a few value types (https://www.w3schools.com/js/js_json_syntax.asp):

  • a string
  • a number
  • an array
  • a boolean
  • null
  • a JSON object (a dictionary with tags like { "first" : "John", "last" : "Doe" }). This allows nesting.

A JSON object is a set of tag-value pairs. The tag and value are separated by : and pairs are separated by ,.

An array is a list of JSON values. So for example [ "hello", world" ] is a JSON array with 2 strings and [ 12, 54 ] is a JSON array with two numbers.

Your parameter list ["pregnancy_week": 0, "body_height": 198, ... is not an array but a dictionary instead. A Swift dictionary is translated to an JSON object, not a JSON array.

The \ you see printed acts as escape character. This escape character is used to allow you to have a " inside the string.

That's just a few things that I hope will help understand things a bit better. Your questions are pretty basic, which is fine and it's great you want to understand things. But instead of us explaining everything here, I think it would be best if you'd read about the structure of JSON and how JSON works in Swift on your own.

meaning-matters
  • 21,929
  • 10
  • 82
  • 142
  • Thank you for answer! It was a good read, and I re-read all about JSON. I know this parameter list is not array :) I asked about array in "products_used" key. I still wonder how I can send this "products_used" array with object to post request without escape characters or how to sent this array correctly to url parameters? – handzel Nov 15 '20 at 20:06