Having problems integrating with SimpleUPC API on iOS - ios

So I'm relatively new to this and I'm running into a problem that has me pretty stumped. SimpleUPC provides a pretty simple API but they have the following format for a JSON request:
{
"auth":"Your API Key",
"method":"MethodName",
"params": {
"paramName":"paramValue",
"paramName2":"paramValue2",
},
"returnFormat":"optional"
}
I also download their Ruby sample which I have verified does work from the command line.
# Sample API calls using JSON...
host = "api.simpleupc.com"
path = "/v1.php"
# An example query for FetchProductByUPC method
request = {
"auth" => 'Your-API-Key',
"method" => 'FetchProductByUPC',
"params" => {"upc" => '041383096013'}
}
json = request.to_json()
response = Net::HTTP.start(host) { |http|
http.post(path, json, initheader = {'Content-Type' =>'text/json'})
}
output = response.body
puts output
Ok so far so good. But here's my code that is trying to do the same thing but I am getting errors complaining about missing parameters.
NSDictionary *requestDict = #{#"auth": kSimpleAPIKey, #"method": #"FetchProductByUPC", #"params":#{#"upc": code}};
[[SimpleUPCClient sharedClient] getPath:#""
parameters:requestDict
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Response: %#", responseObject);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[TMReportingHandler handleError:error fatal:NO];
}];
I know this has got to be something simple I'm doing wrong but I can't figure it out. Anyone?

Wow, I knew it was something simple. Turns out it was expecting a POST instead of a GET...I switched it and it worked immediately.

Related

(POST Request) Parse JSON elements from a URL response in Objective-C

I am having trouble with parsing/returning JSON from a URL response. Here is an example
lets say I submit this to a server [POST not GET]
firstname=first&lastname=last&age=99
and the response from the server is this
{
"person":{
"firstname":"first",
"lastname":"last",
"info":{
"age":"99"
}
}
}
how would I retrieve this information (certain elements)
lets say I JUST want the persons age so the return string should be just "99"
or how do I JUST return the lastname or JUST the firstname, another thing how would I pass the returned element into the next POST request without the user having to type it again?
if anyone can find an example that would be fantastic :)
Thank You!
lets say the name of this data is json (you called it response). This is a dictionary. What this means is that it has key/value pairs. To access it do the following:
To get any of this information in the dictionary, all you need is a one line of code!!
To get detail of a person's first name,
[response valueForKeyPath:#"person.firstname"];
To get last name :
[response valueForKeyPath:#"person.lastname"];
To get age :
[response valueForKeyPath:#"person.info.age"];
Hmm... If it were me, I would just get the NSDictionary, then look inside the NSDictionary.
To get age:
You would want to get { "firstname":"first", "lastname":"last", "info":{ "age":"99" } }, so do:
[responseObject objectForKey:#"person"];
After you do that, you would want to get { "age":"99" }. To do that, you should use
[[responseObject objectForKey:#"person"]objectForKey:#"info"];
After that, 1 last step to get the value for age:
[[[responseObject objectForKey:#"person"]objectForKey:#"info"]objectForKey:#"age"];
And then, you have age.
To get firstname
Just find the object for key firstname by doing:
[[responseObject objectForKey:#"person"]objectForKey:#"firstname"];
To get lastname
[[responseObject objectForKey:#"person"]objectForKey:#"lastname"];
... The rest should follow the same rule.
How to pass it back to a POST request
Well, the POST request takes in an id parameters. This is where you would put the dictionary. To do this correctly without having to deal with any asynchrony, you would have to make the POST request inside the GET request. For example:
[manager GET:<your GET url>
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
[manager POST:<your POST url>
parameters:responseObject
success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(#"Success!"); }
failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(#"Error: %#", error); }];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(#"Error: %#", error); }];
Well, that's pretty much it. Hope this helped :)

Best practices: error handling Ruby(Rails) to iOS(AFNetworking)

New to RoR, not new to iOS.
So I'm using AFNetworking to handle all of my api calls. For example:
[[TJAPIClient shared] GET:#"api/taxonomies"
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject)
{
NSMutableArray *taxonomies = [NSMutableArray arrayWithCapacity:[responseObject[#"taxonomies"] count]];
[responseObject[#"taxonomies"] each:^(NSDictionary *taxonomyInfo)
{
TJTaxonomy *taxonomy = [TJTaxonomy modelWithRemoteDictionary:taxonomyInfo];
[taxonomies addObject:taxonomy];
}];
if (block) block(taxonomies, nil);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error fetching taxonomies: %#", error);
[UIAlertView showAlertViewWithTitle:#"Server Error"
message:error.localizedDescription
cancelButtonTitle:nil
otherButtonTitles:nil
handler:nil];
if (block) block(nil, error);
}];
And on RoR, nothing fancy:
def create
#user = User.new(user_params)
respond_to do |f|
if #user.save
f.html {}
f.json { render json: #user }
else
f.html {}
f.json { render json: #user.errors.full_messages }
end
end
end
As it stands, the code that is written above returns errors through the success block and the data looks like this:
{
errors = (
#"Email can't be blank",
#"Password can't be blank"
)
}
So all I want to know is how I can send these errors through the failure block, as well as send the respective errors as an NSError object. If that's not possible, then perhaps some best practices for this kind of thing. Again, I'm very new to the RoR world (loving it, though!).
Thank you!
You'll have to check the responseObject of the success callback block if you want to handle those errors.
if (responseObject[#"errors"])
NSLog(#"Oh noes!");
}
The error block is a passthrough1 for NSURLSessionTaskDelegate and will be when URLSession:task:didCompleteWithError: gets called with an error.
NSURLSessionTaskDelegate
Server errors are not reported through the error parameter. The only errors your delegate receives through the error parameter are client-side errors, such as being unable to resolve the hostname or connect to the host.
Well, it will also get called on any serialization errors from the response serializer.
You can take a look at AFURLSessionManagerTaskDelegate's URLSession:task:didCompleteWithError: method to see how it works.

AFHTTPClient putpath method

I have problem with my below funct:
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
sportid, #"sport",
country, SC_PAIS,
team, SC_TEAM,
token, SC_TOKEN,nil];
[[SCHTTPClientServer sharedClient] setParameterEncoding:AFJSONParameterEncoding];
[[SCHTTPClientServer sharedClient] putPath:#"calendarelemfilters/teams" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"RESPonsee %#",responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"ERROR %#",[error localizedDescription]);
}];
this is my code. I have below error- How can i fix it?
Thanks
"""RESPONSE STRING: <>Apache Tomcat/7.0.26 - Error report HTTP Status 400 - Required String parameter 'token' is not presenttype Status reportmessage Required String parameter 'token' is not presentdescription The request sent by the client was syntactically incorrect (Required String parameter 'token' is not present).Apache Tomcat/7.0.26
2013-09-19 13:10:24.254 ISportsCal[834:907] ERROR Expected status code in (200-299), got 400"""
It's all there in the error message. The server is expecting a parameter called token and you aren't passing one in the expected format.
What is SC_TOKEN? Possibly a capitalization error?
Are you sure the server is expecting JSON?
Is the server expecting any additional headers?
You may want to download https://github.com/AFNetworking/AFHTTPRequestOperationLogger to take a look at your requests. You can download a tool like Postman REST Client, get the put request working there, and then make sure your AFNetworking request matches this.
I have fixed it with postPath. and also i setted "setparameter encoding" as below.
[[SCHTTPClientServer sharedClient] setParameterEncoding:AFFormURLParameterEncoding];
Thanks

How to pass two parameters (NSString) and receive text-plain using Rest-Kit?

I have one service REST/JSON. It looks like:
#GET
#Produces(MediaType.TEXT_PLAIN)
#Path("/login/{userName}/{password}")
public synchronized String login(#PathParam("userName") String userName,
#PathParam("password") String password);
How do I consume this using RestKit in IOS?
It's obvious that in order to send canonical restkit requests you ought to have entities, mappings etc. Documentation provides explicit answer of how to do it.
I can also suggest you using the easy way:
[[RKObjectManager sharedManager].HTTPClient postPath:#"your URL string" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"WHOOO");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//
}];
responseObject is what you need.

Getting 401 on PATCH Request sent with AFNetworking/RestKit but 202 sent from Browser

So I have this RESTful API running on top of my Django server by using Tastypie.
So I am doing the following code from javascript, and everything works fine.
var newData = {};
newData["content"] = "This is a new test";
$.ajax({
type: 'patch',
contentType: "application/json; charset=utf-8",
url: "/api/rest/sopsteps/17/",
data: JSON.stringify(newData),
dataType: "json",
success: function(data, status) {
alert("success");
},
error: function(data, status){
alert(data + " STATUS : " + status);
},
});
Now if I do the following using AFNetworking/RestKit I always get a 401 back.
[26/Dec/2012 16:20:20] "PATCH /api/rest/sopsteps/17/ HTTP/1.1" 401 0
NSDictionary* params = [[NSDictionary alloc] initWithObjectsAndKeys: _contentTextView.text, #"content", nil];
NSString *path = [NSString stringWithFormat:#"/api/rest/sopsteps/%#/",((PokaSOPStep *)_step).identifier];
[[objectManager HTTPClient]patchPath:path parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject)
{
_step.content = _contentTextView.text;
NSLog(#"%#", operation.responseString);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
if(operation.responseData)
{
id json = [NSJSONSerialization JSONObjectWithData:operation.responseData options:0 error:nil];
if(!json)
{
NSLog(#"An unexpected error occurred. No JSON from Server");
}
else
{
NSLog(#"An unexpected error occurred.");
}
}
else
{
NSLog(#"The Server is currently not responding.");
}
}];
but if I do it from the browser, I get:
[26/Dec/2012 16:54:57] "PATCH /api/rest/sopsteps/17/ HTTP/1.1" 202 0
Any ideas?! Thanks!
401 is the HTTP code for "unauthorized". The reason you're getting different results in the browser and AFNetworking is that you're logged into the former, but not the latter (you can check this by trying this in another browser).
I don't know what kind of authentication scheme you have set up for your server, but you'll need to log into that on iOS before you'll be able to make that request.

Resources