9

I have a model class like this

class Example() {
  var name:String?
  var age:String?
  var marks:String? 
}

I'm adding data to that model class

let example = Example()
example.name = "ABC"
example.age = "10"
example.marks = "10" 

After that I converted to JSON then I posted

Alamofire.request(URL, method:.post, parameters: example)

Alamofire not accepting parameters only its accepting like parameters = ["":"","",""]-->key value based, so I tried to convert model to JSON, JSON to dictionary, even though not accepting its showing like parameters problem. Exactly I need total model object need to send as a parameter of post method in Alamofire like this:

let example = Example()
Alamofire.request(URL, method:.post, parameters: example) 
halfer
  • 19,824
  • 17
  • 99
  • 186
Tirupatirao
  • 165
  • 3
  • 9
  • i tried like this also let json = SwiftyJSON.JSON(example) Alamofire.request(URL, method:.put, parameters:json, encoding:JSONEncoding.default, headers :Defines.Api.Headers ).responseJSON not accepting – Tirupatirao Apr 27 '17 at 05:06
  • Please read [Under what circumstances may I add “urgent” or other similar phrases to my question, in order to obtain faster answers?](//meta.stackoverflow.com/q/326569) - the summary is that this is not an ideal way to address volunteers, and is probably counterproductive to obtaining answers. Please refrain from adding this to your questions. – halfer Jul 05 '17 at 14:36
  • A good answer appears to have been added below, Tirupatirao, on the same day you asked this question. How did you get on with that? – halfer Jul 05 '17 at 14:36

2 Answers2

8

Since the Alamofire API is only accepting dictionaries, create a dictionary yourself!

Add a method in the model class called toJSON:

func toJSON() -> [String: Any] {
    return [
        "name": name as Any,
        "age": age as Any,
        "marks": marks as Any
    ]
}

Then call this method when calling request:

Alamofire.request(URL, 
    method:.put, 
    parameters:example.toJSON(), 
    encoding:JSONEncoding.default, 
    headers :Defines.Api.Headers )

Alternatively, use SwiftyJSON:

func toJSON() -> JSON {
    return [
        "name": name as Any,
        "age": age as Any,
        "marks": marks as Any
    ]
}

Usage:

Alamofire.request(URL, 
    method:.put, 
    parameters:example.toJSON().dictionaryObject, 
    encoding:JSONEncoding.default, 
    headers :Defines.Api.Headers )
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • i have `struct ProfilePassword: Encodable { private let pw: Password enum CodingKeys: String, CodingKey { case pw = "password_update" } private struct Password: Encodable { let password: String let confirmation: String enum CodingKeys: String, CodingKey { case password = "password" case confirmation = "password_confirmation"}} init(_ password: String) { pw = Password(password: password, confirmation: password) }}`how do i send this model object as a parameter in alamofire? – j.krissa Apr 18 '18 at 13:14
  • 1
    There is nothing generic ? or we need to make it on each class that we want to post through API. I can't believe it – theMouk Nov 26 '19 at 17:33
  • @theMouk Now we have the `Codable` API, which you can use to convert your object to `Data` and then send with Alamofire. But since this question is tagged swift3 and was posted ages ago, `Codable` wasn't available at that time. – Sweeper Nov 26 '19 at 17:36
1

The best way so far is to make your model conform to Encodable then convert you model into json Data like so

let data = try! JSONEncoder.init().encode(example)

then use SwiftyJSON to convert it back to dictionary

let json = try! JSON.init(data: data)
let dictionary = json.dictionaryObject

as Rob said you can also use JSONSerialization if you are not already using SwiftyJSON

let dictionary = try! JSONSerialization.jsonObject(with: data) as! [String: Any]

Then use the dictionary in your parameters

Also Alamofire now supports Encodable parameters with

let urlRequest = JSONParameterEncoder.init().encode(example, into: urlRequest)
Amr Mohamed
  • 2,290
  • 4
  • 20
  • 39
  • 1. If you want to use `JSONEncoder `, it needs to conform to `Encodable`, not `Decodable`. 2. If you use `JSONEncoder`, you don’t need that `init`, e.g., `let data = try! JSONEncoder().encode(example)`. 3. I don’t think that introducing another library, such as SwiftyJSON, adds any value here, e.g. `let dictionary = try! JSONSerialization.jsonObject(with: data) as! [String: Any]` is sufficient. – Rob Sep 03 '19 at 22:23
  • And, in the interest of full disclosure, that `JSONParameterEncoder` (which is a great improvement) is still only in the beta version of Alamofire. (And, again, the `init` is not needed, so you might do `let encoded = try! JSONParameterEncoder().encode(foo, into: request)`.) – Rob Sep 03 '19 at 22:31
  • I meant `Encodable` in the first place cause it's enough for the example as he will only need the encoding part of it. – Amr Mohamed Sep 03 '19 at 22:53
  • The `init` is just a personal preference (a thing) that I like using instead of `()` and it's the same at the end. – Amr Mohamed Sep 03 '19 at 22:54
  • and yes you are totally right about using `JSONSerialization` if SwiftyJSON was not already being used in the codebase. – Amr Mohamed Sep 03 '19 at 22:56