0

I am trying to send an API request that looks like this

[
  {
    "thing": "",
  },
]

Based on an array of an object like this

struct Something: Codable {
  var thing: String? = nil
}

[Something]

AF.request(path, method: .put, parameters: params, encoding: JSONEncoding.default, headers: headers)

It has become very apparent that Alamofire is incapable of doing this and expects the objects to be a dictionary like this [String, Any]

[
  "parentThing": {
    "thing": "",
  },
]

This is not an option here. I have found a handful of possible solutions, none of which have worked in this case.

Any help would be greatly appreciated!

For an exhaustive list of things i have found and tried, https://stackoverflow.com/a/44551842/1386556 or https://stackoverflow.com/a/27027253/1386556 - these result in each of the models being converted to a string like so. Obviously an array of strings is not the intent. It really needs to be an array of JSONObjects.

["{\"thing\":\"\",}"]
DevinM
  • 1,112
  • 1
  • 12
  • 29
  • 1
    "I have found a handful of possible solutions": In theory, solution would be to create yourself the URLRequest, give it your own JSON (with JSONSerialization, URLQueryItem, etc.) and pass that URLRequest to Alamofire. What have you tried – Larme Sep 15 '21 at 19:31
  • @Larme I edited the post and started entering the things i have tried. As i try more i will include them there. – DevinM Sep 15 '21 at 20:09
  • Not tested, but that should do the trick: https://pastebin.com/x7Ugx3tR and it's what're doing the linked answers... – Larme Sep 15 '21 at 20:20
  • Cannot convert value of type 'Data?' to expected argument type 'Parameters?' – DevinM Sep 15 '21 at 20:28
  • Which line causes that error? What’s header type in your case? Do it manually? – Larme Sep 15 '21 at 20:30

2 Answers2

1

Instead of using the request(..., encoding:) version, make your parameters Encodable and use the request(..., encoder: JSONParameterEncoder()) version, which properly supports encoded arrays of values.

Jon Shier
  • 12,200
  • 3
  • 35
  • 37
  • The project is currently using the older function to preform the request for about 50 endpoints. I did what you said, in-line, and still cannot figure out why it fails. The response "succeeds" but server side is failing and returning a failure. Its not serializing the json response back in the logs and finding a fully functional example project has proven rather difficult. Also, importantly, doing it this way poses more issues like decoding the custom error json response from AFError which also lacks any documentation. I am an 8yr android developer working in iOS for the last week :/ – DevinM Sep 17 '21 at 14:39
  • If you `debugPrint(response)` the response you get in the closure, it should give you most of the relevant details of the response. – Jon Shier Sep 17 '21 at 15:42
0

Send data like this [[String: AnyObject]]

Example:

func preparaeData() -> [[String: AnyObject]] {
    var data: [[String: AnyObject]] = [[String: AnyObject]]()
    
    for (item) in yourArray {
      let dataDictionary: [String: AnyObject] = ["thing": item.thing as AnyObject]
      data.append(dataDictionary)
    }
    
    return data
  }
  • [[String: AnyObject]] does work for me. I need to send it minimally [[String?: AnyObject]] but preferably [[AnyObject]]. Notice that my object in the array does NOT have a key. Inside the object is a standard dictionary but i need to send an array of keyless dictionaries or better worded as simple json objects not dictionaries. – DevinM Sep 15 '21 at 20:01