I need send a post json request to an url. This service need two identifiers, ow can I sent it with JSONHTTPClient??
With postman I write:
{
"token" : "apitoken",
"identifier" : 1
}
But with objective c code I dont know how to add this two elements into request:
//add extra headers
[[JSONHTTPClient requestHeaders] setValue:#"MySecret" forKey:#"AuthorizationToken"];
//make post, get requests
[JSONHTTPClient postJSONFromURLWithString:#"http://myd.com/api"
params:#{}
completion:^(id json, JSONModelError *err) {
//check err, process json ...
}];
Populate the params dictionary.
//make post, get requests
[JSONHTTPClient postJSONFromURLWithString:#"http://myd.com/api"
params:#{ #"token": #"apitoken",
#"identifier": #1 }
completion:^(id json, JSONModelError *err) {
//check err, process json ...
}];
See the JSONHTTPClient Class Reference:
postJSONFromURLWithString:params:completion:
params:
a dictionary of key / value pairs to be send as variables to the request
Related
I am trying to fetch all the records present in the airtable but it's only getting me 100 records only but i need to fetch more than 100 records.
loadListings(){
var self = this;
var app_id = "**********";
var app_key = "**********";
axios.get(
"https://api.airtable.com/v0/"+app_id+"/Weekly%20Report?view=Main%20View",
{
headers: { Authorization: "Bearer "+app_key }
}
).then(function(response){
console.log(response.data.records);
self.listings = response.data.records;
}).catch(function(error){
console.log(error)
});
}
Airtable API returns 100 records at most. You can't change that. It has pagination included by default.
You need to make multiple calls to get all your data. The response will include a property called offset. You need to retrieve it and use it in your next call.
https://api.airtable.com/v0/"+app_id+"/Weekly%20Report?view=Main%20View&offset=previously_saved_offset
The next call will return a new offset and so one until you reach the end of your records.
TLDR:
You could try using a recursive function that executes when an offset exists in the http response (json).
Acknowledgment:
This solution took 7 hours of research, troubleshooting, and advice from the great, and powerful Doug. The project uses Alamofire to perform http requests, and SwiftyJson to access the JSON.
Cause:
In the Airtable documentation, they state their rate limit is 100 items per request. If a request has more than 100 items, the request will include an offset.
They give an instruction to include the offset in your next request to get the next 100 results. But, they don't explain or demonstrate how to do it.
Solution:
It's been tested to retrieve 2,565 items from 25 http requests. Written in Swift, the logic is simple:
Write a recursive function with an argument for an optional offset. Call the function without the offset. Check the http response (json) for the offset. If the offset exists, store the http request (json) in an array outside the function. Then, call that same function from inside itself - this time with the offset.
Extended code here.
func requestAirtableRecords(forTable table: String, withTableView tableView: String, withOffset offset: String?, completion: #escaping ([JSON]) -> ()) {
let parameters: [String: Any] = offset != nil ? ["view": tableView, "offset": offset!] : ["view": tableView]
do {
let url: URLRequest = try self.requestRecordsURL(table: table, method: HttpRequest.get, parameters: parameters)!
Alamofire.request(url).responseJSON { (response) in
switch response.result {
case .success(_):
let json = JSON(response.result.value!)
self.jsonArray.append(json)
let nextOffset = json["offset"]
if nextOffset.exists() {
self.requestAirtableRecords(forTable: table, withTableView: tableView, withOffset: nextOffset.stringValue, completion: { _ in
completion(self.jsonArray)
})
} else {
completion(self.jsonArray)
}
case .failure(let error):
print(error)
}
}
} catch {
print("Error: Unable to request records from Airtable.")
}
}
I am using Alamofire in my App. This is my Alamofire request code
let params: [String:AnyObject] = ["email": self.signin_Email.text!, "password": self.signin_Password.text!]
Alamofire.request(.GET, "http://DomainName/api/App/Sign_Up", parameters: params, encoding:.JSON)
.responseJSON { response in
debugPrint(response)
}
when i put debugPrint(reponse)
what i got is this
[Request]: { URL:
http://Domain/api/App/Sign_Up } [Response]: nil [Data]:
0 bytes [Result]: FAILURE: Error Domain=NSURLErrorDomain Code=-1017
"cannot parse response" UserInfo={NSUnderlyingError=0x7ffe0840e700
{Error Domain=kCFErrorDomainCFNetwork Code=-1017 "(null)"
UserInfo={_kCFStreamErrorCodeKey=-1, _kCFStreamErrorDomainKey=4}},
NSErrorFailingURLStringKey=http://Domain/api/App/Sign_Up,
NSErrorFailingURLKey=http://Domain/api/App/Sign_Up,
_kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-1, NSLocalizedDescription=cannot parse response}
Here i am always getting the response status as Failure. I am not able to figure out what's going on. (using mvc4 as backend).
This is the Api method that accepts the above given request and returns a JSON Data
[System.Web.Http.HttpGet]
public JsonResult Sign_Up(string email,string password)
{
email = email;
password = password;
System.Web.Mvc.JsonResult usertoreturn = new System.Web.Mvc.JsonResult();
SignUpViewModel signupviewmodel = new SignUpViewModel();
usermodeltocheck.SetPassword(password);
usermodeltocheck.MembershipDate = DateTime.Now;
usermodeltocheck.IsMember = true;
usermodeltocheck.PublicKey = Guid.NewGuid().ToString("N");
usermodeltocheck.MembershipStatus = true;
usertoreturn.Data = Helper.UpdateUser(usermodeltocheck);
}
usertoreturn.JsonRequestBehavior = System.Web.Mvc.JsonRequestBehavior.AllowGet;
return usertoreturn;
}
UPDATE #1 I have created a new method named test that accepts a parameter.The method just returns the parameter value .I tried the sample code available in Github and its working. I am able to get proper response if I am avoiding parameters argument in Alamofire request Method. like
Alamofire.request(.GET, "http://DomainName/api/App/Test", encoding: .JSON).responseJSON{
response in
debugPrint(response)
}
here I am getting a SUCCESS response. I have updated my code like this
Alamofire.request(.GET, "http://DomianName/api/App/Test?test=testing", encoding: .JSON).responseJSON{
response in
debugPrint(response)
}
here also I am getting SUCCESS response. The Error occurs when I pass parameter value to the argument parameters parameters: ["test":"testing"].
also I set my parameters like this
let params = ["test":"testing"]
Alamofire.request(.GET, "http://DomianName/api/App/Test", parameters : params ,encoding: .JSON).responseJSON{
response in
debugPrint(response)
}
in this way also i am getting my response to FAILURE
May be its not an answer you are looking for but for me removing a parameter from Alamofire request method did the trick. Here is the change:
let params : [String:AnyObject] = ["email":self.signin_Email.text!,"password":self.signin_Password.text!]
let request = Alamofire.request(.GET, "http://DomianName/api/App/Sign_Up", parameters: params).responseJSON{
response in
switch response.result{
case .Success(let data) :
let json = JSON(data)
print(json)
case .Failure(let error):
print("Error : \(error)" )
}
}
I have removed encoding:.JSON from my Alamofire request method parameter list and that's it...
Try to print out all the data in response using the following:
let URLString = "http://DomainName/api/App/Sign_Up"
Alamofire.request(.GET, URLString, parameters: params, encoding:.JSON)
.responseJSON { response in
debugPrint(response)
}
Once you print it out, if you could update your question, we could help further. I'll update my answer accordingly afterwards. 👍🏼
Update #1
Okay, so the NSURLErrorDomain Code=-1017 points out that your server is most likely misbehaving. Are you able to successfully use cURL, Postman, Paw or some other HTTP client to hit the service? Once you get one of those working, you should use debugPrint on the `request object to compare.
let URLString = "http://DomainName/api/App/Sign_Up"
let request = Alamofire.request(.GET, URLString, parameters: params, encoding:.JSON)
.responseJSON { response in
debugPrint(response)
}
debugPrint(request)
This will show you the cURL command for the request.
I know this is kind of old but I stumbled upon this looking for something else. From what I have seen, I tend to get errors in this situation any time params are passed as JSON encoded with a .GET instead of a .POST
Changing the server to take a post for the URI makes everything flow correctly, and I guess in theory that is correct behavior, since if you aren't passing the values in the URL, you are technically posting the JSON to the endpoint.
I am using Manger class for request. When I compile it shows
<unknown>:0: error: tuple pattern cannot match values of the non-tuple type 'Response<String, NSError>' Error`.
Its working fine in old Swift Xcode 6.*. But in Xcode 7.* its not working.
let aManager = Manager.sharedInstance
aManager.request(.GET, URLStrings.BASE_URL + URLStrings.CATEGORIES)
.responseString { _, _, result in
print("Response String: \(result.value)")
}
.responseJSON { _, _, result in
print("Response JSON: \(result.value)")
}
On clicking responseString it shows ?
Kindly Help me.
I supposed that you are using the 3.0+ Alamofire.
I encounter this problem recently, here is my solution:
for you code replace _, _, result to response and query the response data by response.data or response.result.value
For more information about the new response structure, you can check the official document here: enter link description here
Hope these helps.
You're on the Alamofire 3.0.0-beta.1 pre-release. You should switch back to Alamofire 2.0.2 (the latest release) until we have all the documentation and migration guides up-to-date.
I change my code in to this form. Now What I have to do is Convert data to JSon Object my self. But its working now for me.
let aManager = Manager.sharedInstance
aManager.request(.GET, URLStrings.BASE_URL + URLStrings.CATEGORIES )
.response {
(request, response, data, error) in
if let response = response {
print("GET REQUEST: \(request?.description)")
print("GET REQUEST: \(response.statusCode)")
if response.statusCode == 200 || response.statusCode == 201 {
}
}
else {
}
}
I check the official document here: Response Serializers
In the document, find Response Serializers, read the example code, I post it in here:
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
.responseJSON { response in
debugPrint(response) // prints detailed description of all response properties
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
Hope it can helps you~
I need to make a POST request with an HTTP Body with a JSON object, but I also need to use url query parameters in the same request.
POST: http://www.example.com/api/create?param1=value¶m2=value
HTTP Body: { foo : [ bar, foo], bar: foo}
Is this supported by Alamofire? How would I go about doing this?
This is definitely a valid use case. I've ran into similar issues with trying to append access tokens as query parameters to a POST request. Here's a function that should make things a bit easier for the time being that is similar to your approach.
func multiEncodedURLRequest(
method: Alamofire.Method,
URLString: URLStringConvertible,
URLParameters: [String: AnyObject],
bodyParameters: [String: AnyObject]) -> NSURLRequest
{
let tempURLRequest = NSURLRequest(URL: NSURL(string: URLString.URLString)!)
let URLRequest = ParameterEncoding.URL.encode(tempURLRequest, parameters: URLParameters)
let bodyRequest = ParameterEncoding.JSON.encode(tempURLRequest, parameters: bodyParameters)
let compositeRequest = URLRequest.0.mutableCopy() as NSMutableURLRequest
compositeRequest.HTTPMethod = method.rawValue
compositeRequest.HTTPBody = bodyRequest.0.HTTPBody
return compositeRequest
}
With that said, could you make sure to put in a feature request issue on the Github? This is certainly something we need to figure out how to make easier in Alamofire since it's such a common use case. If you could put in a really good description of your use case, then I'm sure it will get attention. I will certainly help press to get support added.
At this point, I've decided to solve this by manually encoding an NSURLRequest with the URL parameters, retrieving the URL from that request, and using that to create the final request. I've created a function to return the query parameter encoded request:
private func queryParameterEncodedRequestURL(urlString: String,
values: [String]) -> NSURL {
let URL = NSURL(string: urlString)
var request = NSURLRequest(URL: URL)
let parameters = [
"param1": values[0]!,
"param2": values[1]!
]
let encoding = Alamofire.ParameterEncoding.URL
(request, _) = encoding.encode(request, parameters: parameters)
return (request.URL, nil)
}
This works fine, but I would definitely like to see Alamofire support multiple encoding types more easily. This feels like a workaround to me.
In my -request:didLoad: delegate method I'm NSLoging the results but I can't figure out what's the content?
It looks like result is an NSArray but what is inside it? how do I parse the data?
A sample of the log looks like this:
result: (
{
"fql_result_set" = (
{
uid2 = 1234567;
},
{
uid2 = 12345678;
}
);
name = queryID;
},
{
"fql_result_set" = (
{
"birthday_date" = "05/12/1987";
name = "John Doe";
},
{
"birthday_date" = "03/01/1978";
name = "Jane Doe";
}
);
name = queryBirthday;
}
)
The Facebook iOS tutorial, in "Step 6: Using the Graph API", says
Note that the server response will be in JSON string format. The SDK uses an open source JSON library https://github.com/stig/json-framework/ to parse the result. If a parsing error occurs, the SDK will callback request:didFailWithError: in your delegate.
A successful request will callback request:didLoad: in your delegate. The result passed to your delegate can be an NSArray, if there are multiple results, or an NSDictionary if there is only a single result.
In your example, everything printed by NSLog inside "()" is part of an NSArray, while everything inside "{}" (which also have keys incidentally) is part of an NSDictionary and therefore accessible by key (name).
http://developers.facebook.com/docs/mobile/ios/build/
According to https://developers.facebook.com/docs/reference/api/, all 'responses' are JSON-Objects. To parse these, iOS 5 provides a class called NSJSONSerialization (NSJSONSerialization Class Reference)
You normally parse it as follows:
NSDictionary *dictionaryJSON = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&error];