When I upgraded to latest everything (Alamo 4, Swift 3 and XC 8) the following stopped posting parameters and I dont have a clue why...
let params = ["stripeToken": token.tokenId,
"name": name,
"email": email
]
Alamofire.request(requestString, method: .post, parameters: params, encoding: JSONEncoding.default)
.responseJSON { (response) in
if response.result.value is NSNull {
return
}
I had a similar issue, I changed encoding from JSONEncoding.default to URLEncoding.httpbody or encoding: URLEncoding.default
Alamofire.request(URL, method: .post, parameters: params, encoding: URLEncoding.httpBody).responseJSON { response in
if let data = response.data {
let json = String(data: data, encoding: String.Encoding.utf8)
print("Response: \(json)")
}
}
I have the same issue and finally fixed it. URLEncoding.httpBody didn't work for me... but URLEncoding.default did.
So I changed JSONEncoding.default to URLEncoding.default.
It's now passing the parameters to the backend.
Alamofire.request(loginURL, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil)
Everything works exactly as it should. Here's a quick example demonstrating that fact.
func testPostingJSON() {
let urlString = "https://httpbin.org/post"
let params: Parameters = [
"stripeToken": "token_id",
"name": "cnoon",
"email": "cnoon#alamofire.org"
]
let expectation = self.expectation(description: "should work")
Alamofire.request(urlString, method: .post, parameters: params, encoding: JSONEncoding.default)
.responseJSON { response in
if let json = response.result.value {
print("JSON: \(json)")
} else {
print("Did not receive json")
}
expectation.fulfill()
}
waitForExpectations(timeout: 5.0, handler: nil)
}
Hopefully that example helps you pinpoint the issue. Cheers. 🍻
Related
I am not being able to get the response body that I need to store in the logs along with the request body. The only time I'm able to get the response body is when the request fails.
I've followed the blog post that solved my issue on getting the request body while using body-parser plugin - https://www.express-gateway.io/exploit-request-stream/.
const { PassThrough } = require("stream");
const jsonParser = require("express").json();
const urlEncodedParser = require("express").urlencoded({ extended: true });
module.exports = {
name: 'body-parser',
policy: actionParams => {
return (req, res, next) => {
req.egContext.requestStream = new PassThrough()
req.pipe(req.egContext.requestStream)
return jsonParser(req, res, () => urlEncodedParser(req, res, next))
}
}
};
When the request does work:
{ res: { statusCode: 400 },
req:
{ body: { a: 'b' },
headers:
{ ... } },
responseTime: 310 }
When it does not work:
{ res: { body: 'Bad gateway.', statusCode: 502 },
req:
{ body: { a: 'b' },
headers:
{ ... } },
responseTime: 1019 }
this code alone is not enough to get the response body. This will simply hook in the request body processing and make it available to EG in a parsed way. In case you want to hook in the response too, you will need to write an hook in the response object, once it's done.
You can find an example code here
I hope that helps!
V.
I am going to post a request via alamofire. I can post request with Postman. Response return true (201 code). However when I am try with Alamofire returns 404 code. What's wrong?
My codes:
let headers: HTTPHeaders = [
"Authorization": "Basic xxxxxxxxxxxx",
"content-type": "application/json"
]
let parameters:[String:Any] = [
"xxx":123,
"yyy":"test",
"zzz":"iphone"
]
Alamofire.request(myUrl, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON { response -> Void in
switch response.result {
case .success:
print(response.response?.statusCode)
break
case .failure(let error):
print(error)
}
}
Return this message :
success {
message = "No HTTP resource was found that matches the request URI 'https://xxxxx/PostErrorFeedBack'.";
}
Try this one hope it may help you !!
let headers = [
"Authorization": "Basic xxxxxxxxxxxx"
]
let parameters = [
]
Alamofire.request(.POST, "url", parameters: parameters, headers: headers, encoding: .JSON)
.validate(contentType: ["application/json"])
.responseJSON { response in
if response.response?.statusCode == 200 {
print("Success with JSON: \(response.result.value)")
}
else {
let error = response.result.value as! NSDictionary
let errorMessage = error.objectForKey("message") as! String
print(errorMessage)
failure(errorMessage)
}
}
you can try this method for using Alamofire as this worked for me.
let headers = [
"Accept": "application/json",
"Authorization" : "Authorization: Bearer ", //if any
"Cookie" : "Cookie" //if any
]
let parameterDict: NSDictionary = NSDictionary.init(objects: [nameTextField.text!, reportTextView.text!], forKeys: ["Name" as NSCopying,"Message" as NSCopying])
Alamofire.request("API",method: .post, parameters: parameterDict as? [String : AnyObject] , encoding:JSONEncoding.default, headers:headers) .responseJSON { response in switch response.result {
case .success(let JSON):
print("Success with JSON: \(JSON)")
let response = JSON as! NSDictionary
case .failure(let error):
print("Request failed with error: \(error)")
}
}
I'm trying to implement post webservice in angular2.
I have tried to hit the URL through postman and its working. But when i'm trying to implement it in angular, I'm not getting any response.
The following is my code sample:
load(username, password) {
console.log(username," ", password);
let postData = {"username":username, "password" : password,
"userdeviceInfo": [{
"deviceId": "APA91bGUZuKVbqur7Qq2gy2eyomWgXkIU5Jcmmtmgl4IGuzVzwiJVMZgAHj3Bx6yrnW0oEZlEtB9XdcR6AOpKyEMVSWwQ_UIfNX6T0iwq28hnufOhauVdTYZQSWWPAdDrdg58cjnL5T-",
"platform":"Android"
}]};
//let body= JSON.stringify(postData);
//console.log("body---"+body)
this.headers = new Headers();
this.headers.append("Content-Type", 'application/json');
this.requestoptions = new RequestOptions({
method: RequestMethod.Post,
url: this.url,
headers: this.headers,
body: JSON.stringify(postData)
})
console.log("body---"+this.requestoptions)
return this.http.request(new Request(this.requestoptions))
.map((res: Response) => {
if (res) {
console.log(res.json());
return [{ status: res.status, json: res.json() }];
}})
.subscribe(res => this.data = res);
the error i'm recieving is:
XMLHttpRequest cannot load "MY_URL". Response for preflight has invalid HTTP status code 500
I'm kind of stuck here. Can anyone help me find where am i going wrong?
here is a POST example:
rate(url: string, body: { value: number}) {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(url, body, options).toPromise().then(
response => response.json(),
err => err
);
}
Of course you can delete toPromise() to use observables, this is for an example app :)
hope this can help you.
You can use this way to make a http post :
let headers = new Headers();
let body = {"username":username, "password" : password,
"userdeviceInfo": [{
"deviceId": "APA91bGUZuKVbqur7Qq2gy2eyomWgXkIU5Jcmmtmgl4IGuzVzwiJVMZgAHj3Bx6yrnW0oEZlEtB9XdcR6AOpKyEMVSWwQ_UIfNX6T0iwq28hnufOhauVdTYZQSWWPAdDrdg58cjnL5T-",
"platform":"Android"
}]};
headers.append('content-type', 'application/json');
return this.http.post("theurl", '', {
body : JSON.stringify(body),
headers : headers
})
.map(res => res.json())
.subscribe(data=>{
},
err=>{
},
()=>{
})
I am fetching the facebook profile picture like this
let params = ["height": 300, "width": 300, "redirect": false] as [String : Any]
let graphRequest = FBSDKGraphRequest(graphPath: "me/picture", parameters: params, httpMethod: "GET")
let connection = FBSDKGraphRequestConnection()
connection.add(graphRequest, completionHandler: { (connection, result, error) in
if error == nil {
print("profile pic ************\(result)")
}
})
connection.start()
Now I need to access the profile pictures from the ablum and set those in my collectionView . I tried to set the graphPath: "me/album/profile_picture" but no luck . Could anybody give me some hints please ?
You need to find the id of the "Profile Pictures" album and request the photos for that id.
Facebook.albums(user: "me").request({ albums in
albums.first(where: { ($0["name"] as? String) == "Profile Pictures" }).flatMap({
Facebook.photos(album: $0["id"] as! String).request({ photos in
print(photos)
})
})
})
I have made an enum below to make requesting graph api paths easier.
enum Facebook: Graphable {
case albums(user: String)
case photos(album: String)
var path: String {
switch self {
case let .albums(uid):
return "\(uid)/albums"
case let .photos(aid):
return "\(aid)/photos"
}
}
var method: String {
switch self {
case .albums, .photos:
return "GET"
}
}
var params: [String : Any] {
switch self {
case .albums:
return [:]
case .photos:
return [
"height": 300,
"width": 300,
"redirect": false
]
}
}
}
Here is the protocol and extension the enum must conform to.
protocol Graphable {
var path: String { get }
var method: String { get}
var params: [String : Any] { get }
}
extension Graphable {
typealias JSON = [String:Any]
func request(_ handler: #escaping ([JSON]!) -> (), failure: #escaping (Error) -> () = { print($0) }) {
let connection = FBSDKGraphRequestConnection()
let request = FBSDKGraphRequest(
graphPath: path,
parameters: params,
httpMethod: method
)
connection.add(request) {
_ = $0.1.map ({ handler(($0 as? JSON)?["data"] as? [JSON]) }) ??
$0.2.map ({ failure($0) })
}
connection.start()
}
}
I got my answer like this :
import FBSDKCoreKit
import SwiftyJSON
func getFBAlbumID() {
let graphRequest = FBSDKGraphRequest(graphPath: "me/albums", parameters: nil, httpMethod: "GET")
let connection = FBSDKGraphRequestConnection()
connection.add(graphRequest, completionHandler: { (connection, result, error) in
if error == nil
let dictionary = JSON(result)
// print("albums ID are **************\(dictionary)")
if let data = dictionary["data"].array {
print("data of profilePicture ******* \(data)")
if let dict = data.first(where: { ($0["name"].string ) == "Profile Pictures" }) {
let id = dict["id"].string
print("my desired id : ********* \(id)")
self.getFBAlbumPhoto(albumID: id!)
}
}
}
})
connection.start()
}
func getFBAlbumPhoto(albumID: String) {
let params = [ "height": 300, "width": 300, "redirect": false] as [String : Any]
let graphRequest = FBSDKGraphRequest(graphPath: "\(albumID)/photos?fields=source", parameters: params, httpMethod: "GET")
let connection = FBSDKGraphRequestConnection()
connection.add(graphRequest, completionHandler: { (connection, result, error) in
if error == nil {
//print(result)
let dictionary = JSON(result)
print("result are **************\(dictionary)")
}
})
connection.start()
}
Here I am grabbing the ID of the particular album I desire and then make another call to get the photos of that album. Here I am calling a function from inside another function. If someone can help me to write the code in more Swift way that would be helpful, like using closure. Thanks.
How to send Multipart data with RxAlamofire
For instance in Alamofire
let URL = try! URLRequest(url: "http://example.com", method: .post)
Alamofire.upload(multipartFormData: { formData in
// multiaprt
}, with: URL, encodingCompletion: {(result: SessionManager.MultipartFormDataEncodingResult) in
})
How to get same behaviour/function with RxAlamofire?
Or An way of wrapping this function in an Observable?
You can easily wrap that function like this:
func wrapper() -> Observable<SomeResponseType> {
return Observable.create { observer in
let URL = try! URLRequest(url: "http://example.com", method: .post)
Alamofire.upload(
multipartFormData: { formData in
// multiaprt
},
with: URL,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
// convert response in something of SomeResponseType
// ...
observer.onNext(response)
observer.onCompleted()
}
case .failure(let encodingError):
observer.onError(encodingError)
}
})
return Disposables.create()
}
}