Alamofire: Sending JSON as Request Parameter

Sending JSON object as a post parameter using Alamofire

You can try this one:

var dict : [String: Any] = [:]

dict["type"] = "Step"
dict["data"] = ["2015-08-02": 8574];

let params: [String: Any] = ["r_id": "someName",
"data": String.jsonString(data: dataDict)];

Here jsonString is an extension of String

static func jsonString(data : Any) -> String {

var jsonString = "";

do {

let jsonData = try JSONSerialization.data(withJSONObject: data, options: .prettyPrinted)
jsonString = NSString(data: jsonData, encoding: String.Encoding.utf8.rawValue)! as String

} catch {
print(error.localizedDescription)
}

return jsonString;
}

POST Json to API with Alamofire?

I just show how I work with this.

You don't have to convert your parameters to JSON. It's code from Alamofire.

/// A dictionary of parameters to apply to a `URLRequest`.
public typealias Parameters = [String: Any]

Use this method instead of your:

Alamofire.request(url, method: method, parameters: parameters, encoding: encoding, headers: customHeaders)

Try this:
Instead of your request.httpBody = jsonData you can pass your json in parameters.

Your whole code will be:

func request(json: [String:Any]) {

Alamofire.request(urlString, method: .post, parameters: json, encoding: JSONEncoding.default).responseJSON {
(response) in
print(response)
}

}

If you are interested in my approach:

func makePick(request: MakePickRequest, completionHandler: @escaping APICompletionHandler) {
let parameters = request.converToParameters()
Alamofire.request(Endpoints.makePick, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseJSON { response in
self.handleResponse(response: response, completionHandler: completionHandler)
}
}

Request:

struct MakePickRequest: GeneralRequest {
let eventId: Int64
let sportId: String
let pickType: PickType
let betType: BetType
let amount: Int

func converToParameters() -> [String : String] {
return ["event_id": String(eventId), "sport_id": sportId,
"pick_type": pickType.rawValue, "bet_type": betType.rawValue,
"amount": String(amount)]
}
}

Structure with endpoints:

struct Endpoints {
// Development baseURL
static let baseURL = "http://myurl/"

private static let apiVersion = "api/v1/"

static var fullPath: String {
return "\(baseURL)\(apiVersion)"
}

// MARK: - User endpoints (POST)
static var login: String {
return "\(fullPath)users/login"
}

static var signUp: String {
return "\(fullPath)users/signup"
}

...
}

Outside of any class (but import SwiftyJSON is obligatory):

typealias APICompletionHandler = (_ data: JSON?, _ error: NSError?) -> Void

Handle response:

private func handleResponse(response: DataResponse<Any>, completionHandler: APICompletionHandler) {
self.printDebugInfo(response)
switch response.result {
case .success(let value):
self.handleJSON(data: value, handler: completionHandler)
case .failure(let error):
print(error)
completionHandler(nil, error as NSError?)
}
}

private func handleJSON(data: Any, handler: APICompletionHandler) {
let json = JSON(data)
let serverResponse = GeneralServerResponse(json)
if (serverResponse?.status == .ok) {
handler(serverResponse?.data, nil)
} else {
handler(nil, self.parseJsonWithErrors(json))
}
}

GeneralServerResponse (depends on your server API):

import SwiftyJSON

final class GeneralServerResponse {
let data: JSON
let status: Status

init?(_ json: JSON) {
guard let status = json["status"].int else {
return nil
}

self.status = Status(status)
self.data = json["data"]
}

enum Status {
case ok
case error
case unauthorized

init(_ input: Int) {
if input >= 200 && input < 400 {
self = .ok
} else if input == 403 {
self = .unauthorized
} else {
self = .error
}
}
}
}

My actual example of usage.

This is outside:

func +=<K, V> ( left: inout [K : V], right: [K : V]) { for (k, v) in right { left[k] = v } }

Example of request:

func makePick(request: MakePickRequest, completionHandler: @escaping APICompletionHandler) {
var parameters = ["auth_token": Preferences.getAuthToken()]
parameters += request.converToParameters()
manager.apiRequest(url: Endpoints.makePick, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseJSON { response in
self.handleResponse(response: response, completionHandler: completionHandler)
}
}

SessionManager extension to add headers for all requests:

extension SessionManager {
func apiRequest(url: URLConvertible, method: HTTPMethod, parameters: Parameters? = nil, encoding: ParameterEncoding, headers: HTTPHeaders? = nil) -> DataRequest {
var customHeaders: HTTPHeaders = ["api-key" : "1wFVerFztxzhgt"]
if let headers = headers {
customHeaders += headers
}
return request(url, method: method, parameters: parameters, encoding: encoding, headers: customHeaders)
}
}

In APIManager class:

private let manager: SessionManager

init() {
manager = Alamofire.SessionManager.default
}

Call example:

apiClient.makePick(request: request) { data, error in
if let error = error {
print(error.localizedDescription)
return
}
if let data = data {
// data is a JSON object, here you can parse it and create objects
}
}

Example of class:

import SwiftyJSON

final class MyClass {
let id: Int
let username: String
let parameter: Double

init?(_ json: JSON) {
guard let id = json["id"].int, let username = json["username"].string,
let parameter = json["parameter"].double else {
return nil
}

self.id = id
self.username = username
self.parameter = parameter
}
}

How can I post request with order of json in swift with alamofire?

JSON order isn't typically important, as the JSON spec doesn't define it as a requirement for JSON objects, but some poorly engineered backends do require it. You really need to check the requirements of the backend you're communicating with.

Additionally, Swift's Dictionary type is arbitrarily ordered, and that order may change between runs of your app as well as between versions of Swift used to compile your code.

Finally, Swift's JSONEncoder, and Apple's JSONSerialization type both offer no way to require strict ordering. At most, JSONSerialization offers the .sortedKeys option, which will give you a guaranteed (alphabetical) order, but it may not be the order you declared your parameters in. Using an alternate Encoder, if you have Codable types (which I recommend instead of SwiftyJSON), may give you a better guarantee of order, but you should only really care if it's a requirement of your backend.

As an aside, I suggest you use the static HTTPHeader properties for your HTTPHeaders value, instead of using raw strings, it's much more convenient. For example:

let headers: HTTPHeaders = [.accept("application/json"),
.contentType("application/json")]

Alamofire - add both query parameter and body

Alamofire's URLEncoding has an initializer that gets destination as parameter. Based on documentation:

Destination defining where the encoded query string will be applied.
.methodDependent by default.

By default .methodDependent case checks the HTTP method of the request and only on .get, .head and .delete requests it encodes the passed parameters in the URL.

Given that fact, you never see paramA in your request (not even in the body) because you override it in the following line:

// here body is already serialized to Json
request.httpBody = Data(bodyInJsonString.utf8)

So, instead of using the default URLEncoding, you can simply call URLEncoding's initializer directly passing as destination the .queryString case like this:

// here I am specifying `paramA` value
request = try URLEncoding(destination: .queryString).encode(request, with: parameters)

// here body is already serialized to Json
request.httpBody = Data(bodyInJsonString.utf8)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")

That way you will have a request with paramA in the URL and your JSON as a body.

iOS | Alamofire, how to send raw JSON data to body

Maybe you want something like this :

        var memberJson : String = ""
do{
let jsonEncoder = JSONEncoder()
let jsonData = try jsonEncoder.encode(yourJson)
memberJson = String(data: jsonData, encoding: String.Encoding.utf8)!


}catch{}

var request = URLRequest(url: URL(string: "url here")
request.httpMethod = HTTPMethod.post.rawValue
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = (memberJson).data(using: .unicode)
AF.request(request).responseJSON{response in }

Alamofire: Sending JSON as request parameter

I don't know Alamofire, but I just googled for it and found something in its ReadMe on GitHub....

let parameters = [
"foo": "bar",
"baz": ["a", 1],
"qux": [
"x": 1,
"y": 2,
"z": 3
]
]

Alamofire.request(.POST, "http://httpbin.org/post", parameters: parameters)
// HTTP body: foo=bar&baz[]=a&baz[]=1&qux[x]=1&qux[y]=2&qux[z]=3

https://github.com/Alamofire/Alamofire

Here you have an Dictionary (Dictionary is like a JSON) and also a parameter with another Dictionary(JSON) as value of a parameter...

Is that what you need?



Related Topics



Leave a reply



Submit