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
Gmsgeocoder Reversegeocodecoordinate: Completionhandler: on Background Thread
How to Delete an App from Itunesconnect/App Store Connect
Uicollectionview's Cellforitematindexpath Is Not Being Called
How to Lock Portrait Orientation for Only Main View Using Swift
iOS App Crashing Every Other Launch, Can't Find Error
How to Turn Flashlight on and Off in Swift
iOS Floating Video Window Like Youtube App
How to Rearrange Views When Autorotating with Autolayout
Facebook Logout Is Not Working in New Sdk V.4.1.0 in iOS
Show Datepicker on Textfield Tap
Get Attribute of Viewcontroller Created with Storyboard
"Rctbundleurlprovider.H" File Not Found - Appdelegate.M
When to Use Uicollectionview Instead of Uitableview
Uiwindow Not Showing Over Content in iOS 13
How to Add Constraint Between a View and the Top Layout Guide in a Xib File
How to Add Text Input in Alertview of iOS 8