IOS - How to handle return calls from a RESTful service API - html

I am using an API to have users create an account within my app.
Now I am able to generate the URL required in objective-C to submit the values and in the API documentation it has the return numbers that will confirm to me what has happened.
My question is how do I relay that information to the user of the app?
The return call is shown to me in a HTML page as plain text.
Any ideas?
Thanks in advance.
///////
2012-10-03 12:24:31.557 Multi Web[72631:15203] Dictionary list - {
Connection = "keep-alive";
"Content-Encoding" = gzip;
"Content-Length" = 26;
"Content-Location" = "signup.php";
"Content-Type" = "text/html";
Date = "Tue, 02 Oct 2012 23:24:32 GMT";
P3P = "policyref=\"/w3c/p3p.xml\", CP=\"ALL CURa ADMa DEVa OUR IND UNI COM NAV INT STA PRE\"";
Server = "Apache/2.2.14 (Ubuntu)";
Status = "200 OK";
TCN = choice;
Vary = "negotiate,Accept-Encoding";
"X-Limit-Key-Limit" = 10000;
"X-Limit-Key-Remaining" = 9992;
"X-Limit-Key-Reset" = 236;
"X-Limit-User-Limit" = 320;
"X-Limit-User-Remaining" = 319;
"X-Limit-User-Reset" = 3600;
"X-Powered-By" = "PHP/5.3.2-1ubuntu4.14";
I got this in my console so I now, I have created the account succesfully.
In the middle it says Status = "200 OK";
How do I use that particular line? If I can hook up a UIAlertView to that then i am where I want to be.
Cheers.

I'm not sure if your situation is related to this question. According to docs from the getPocket API you are using, i see the following:
According to apple docs, the default HTTP method is GET. What you need to do is check the response headers from the API. So what you need to do is change your httpMethod to HEAD like so:
NSMutableURLRequest *modReq = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"www.somesite.com/?something"]];
[modReq setHTTPMethod:#"HEAD"];
Then you can read the values from the header with something like so:
NSURLResponse* response = // the response, from somewhere
NSDictionary* headers = [(NSHTTPURLResponse *)response allHeaderFields];
You can then get the response values, and tell the user whats up accordingly.

It's called designing and creating a user interface.
You send a request to the server and get a response. Your job is to examine the response, recognise what it means, and tell the user in an appropriate way what the response meant. Since the user is not an expert in parsing html, showing the html would almost always be entirely inappropriate.
For a user entering a username and password correctly, the appropriate response is usually that the user can now access the site.

Related

How to pull data from Toggl API with Power Query?

First timer when it comes to connecting to API. I'm trying to pull data from Toggl using my API token but I can't get credentials working. I tried to replicate the method by Chris Webb (https://blog.crossjoin.co.uk/2014/03/26/working-with-web-services-in-power-query/) but I can't get it working. Here's my M code:
let
Source = Web.Contents(
"https://toggl.com/reports/api/v2/details?workspace_id=xxxxx&client=xxxxxx6&billable=yes&user_agent=xxxxxxx",
[
Query=[ #"filter"="", #"orderBy"=""],
ApiKeyName="api-token"
])
in
Source
After that I'm inputting my API Token into Web API method in Access Web content windows but I get an error that credentials could not be authenticated. Here's Toggl API specification:
https://github.com/toggl/toggl_api_docs/blob/master/reports.md
Web.Contents function receives two parameters: url + options
Inside options, you define the headers and the api_key, and other queryable properties, such as:
let
baseUrl = "https://toggl.com/",
// the token part can vary depending on the requisites of the API
accessToken = "Bearer" & "insert api token here"
options = [
Headers = [Authorization = accessToken, #"Content-Type" =
"application/Json"], RelativePath ="reports/api/v2/details", Query =
[workspace_id=xxxxx, client=xxxxxx6 , billable=yes, user_agent=xxxxxxx]
]
Source = Web.Contents(baseUrl, options)
// since Web.Contents() doesn't parse the binaries it fetches, you must use another
// function to see if the data was retreived, based on the datatype of the data
parsedData = Json.Document(Source)
in
parsedData
The baseUrl is the smallest url that works and never changes;
The RelativePath is the next part of the url before the first "?".
The Query record is where you define all the attributes to query as a record.
This is usually the format, but check the documentation of the API you're querying to see if it is similar.

Json put/get/post in Restful webservices not working

I am trying to pass parameters to a server and extract the report in csv format. So the code i have has PUT/GET/POST in the order. I could get GET and POST work, but when i add PUT there is no error just blank screen.
String output1 = null;
URL url = new URL("http://<servername>/biprws/raylight/v1/documents/12345/parameters");
HttpURLConnection conn1 = (HttpURLConnection) url.openConnection();
conn1.setRequestMethod("PUT");
conn1.setRequestProperty("Accept", "application/json");
conn1.setRequestProperty("Content-Type", "application/json; charset=utf-8");
conn1.setDoInput(true);
conn1.setDoOutput(true);
String body = "<parameters><parameter><id>0</id><answer><values><value>EN</value></values></answer></parameter></parameters>";
int len1 = body.length();
conn1.setRequestProperty("Content-Length", Integer.toString(len1));
conn1.connect();
OutputStreamWriter out1 = new OutputStreamWriter(conn1.getOutputStream());
out1.write(body, 0, len1);
out1.flush();
What i am trying to do is pass parameter EN to the report and refresh it, take the output in csv using GET. POST is used for login to the server. I could make GET and POST work and get the output in CSV but not refreshed one.
Appreciate very much any help here.
Thanks,
Ak
What is the response code from the server when using PUT?
A PUT may not actually return a body to display on the screen; often times a PUT will only return a 200 or 204 response code. 204 would clearly mean that the server took the data and applied it, but is not sending you anything back, 200/201 may include a response, but maybe not. It depends on the folks who implemented the API.
https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html (section 9.6)
Should a RESTful 'PUT' operation return something

Correct way to use AFHTTPSessionManager as a singleton?

I'm trying to use AFNetworking 2.0 to perform my network requests but I'm running into some odd behavior. I've subclassed AFHTTPSessionManager as suggested in the documentation and provided a class method that returns a singleton object that has the base url set as well as sets my auth header.
+ (id)sharedInstance {
static dispatch_once_t once;
static MyHTTPClient *sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] initWithBaseURL: NSURLURLWithString:kPlatformAPIBaseURL]];
});
//Uncommenting this line makes the error go away
//sharedInstance.responseSerializer = [AFJSONResponseSerializer serializer];
//get latest session id everytime someone gets an instance of the client
sharedInstance.sessionId = [MySessionManager getSessionId];
return sharedInstance;
}
- (instancetype)initWithBaseURL:(NSURL *)url {
self = [super initWithBaseURL:url];
if(self) {
self.sessionId = [FSSessionManager getSessionId];
self.serializer = [AFHTTPRequestSerializer serializer];
[_serializer setValue:_sessionId forHTTPHeaderField:kAuthorizationHeader];
[_serializer setValue:#"application/json" forHTTPHeaderField:kAcceptHeader];
self.requestSerializer = _serializer;
}
return self;
}
- (void)setSessionId:(NSString *)sessionId {
_sessionId = sessionId;
[self.serializer setValue:_sessionId forHTTPHeaderField:kAuthorizationHeader];
}
My app uses this to make a POST request to authenticate my user. That works great. I then make a GET request to retrieve a list of objects. Also works great. I then make the same GET request and I get back a network error Error Domain=AFNetworkingErrorDomain Code=-1016 "Request failed: unacceptable content-type: application/json" It's the exact same GET request but it fails on the second call. When I uncomment the sharedInstance.responseSerializer line so I create a new instance of the response serializer each time I get a reference to my shared instance then I don't get this error anymore.
Can a responseSerializer not be used multiple times safely? It feels like some sort of state is hanging around across requests. What's the correct way to set this up?
A response serializer can be used multiple times safely. Based on the error message you posted, "unacceptable content-type: application/json ", it appears you're setting responseSerializer to something else elsewhere in your code. JSON will serialize properly as long as it's set to [AFJSONResponseSerializer serializer].

How do I get the cookie values in a backbone.js model?

I have a simple Backbone.js/Bootstrap front end in HTML5 with a Node.js/Restify backend. I am setting cookies in a header response from the server as below:
res.setHeader("Set-Cookie", ["token=ninja", "language=javascript"]);
On the client side, I am making a REST call as
var response = this.model.fetch().success(function(data){
//success
}).error(function(data){
//error
}).complete(function(data){
//complete
});
that callsback a parse method in the model.
How can I read the cookie value in the model?
Include Cookie.js.
You can then reference individual cookies like this:
var token = Cookie.get('token')
# token == 'ninja'
Here is what I figured out. My application has two components - the HTML/js from one domain that talks to a REST sevice on another domain (and therefore is cross-domain.) Because the cookie is set from REST, it appears is not readable across domains. So the web page will not store the cookie even though the server is sending it. One alternative is to use local cookies or use the technique illustrated by http://backbonetutorials.com/cross-domain-sessions/.
Assuming you are using jQuery with Backbone, you can get the headers by defining the parse function in your model by calling getAllResponseHeaders or getResponseHeader:
var model = Backbone.Model.extend({
// the rest of your model
parse: function(resp, xhr) {
var allHeaders = xhr. getAllResponseHeaders();
var cookieHeader = xhr. getResponseHeader("Set-Cookie");
// do something with the headers
return resp;
}
});

Submitting an HTML form in Android without WebView

I was given an assignment to develop a very simple weather app in Android using the data given from
http://forecast.weather.gov/zipcity.php
This would be my first actual android app, my only other experience is watching/reading many tutorials on getting started.
To give some background information of the app, it simply needs to have one activity that is a
text field for the user to enter a city, state combination, or just a zip code. This then needs to be submitted to the website's (listed above) form.
After this has been submitted, my app needs to retrieve page sent in response and display it in a simple layout (possibly a listView of the days of the week).
My first question is, how would I go about submitting a text input to the above website's form? Would I have to know the name of the form's field to submit to it precisely?
In general, how should I start this process?
Edited version:
Using this code:
HttpClient httpClient = new DefaultHttpClient();
HttpPost post = new HttpPost("http://forecast.weather.gov/zipcity.php?inputstring=04419");
HttpResponse httpResp;
try {
httpResp = httpClient.execute(post);
StatusLine status = httpResp.getStatusLine();
Toast.makeText(getApplicationContext(), status.getStatusCode(), Toast.LENGTH_SHORT).show();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
I'm getting a:
10-26 15:29:56.686: DEBUG/SntpClient(59): request time failed: java.net.SocketException: Address family not supported by protocol
error in the debug view. Is this error related? Is my use of toast reasonable for testing if this http interaction is successful?
When you want to see what a post request in passing use Firefox + tamperdata, that way you can look at how to use the webservice.
I took a look at it, I searched for "33129" and when you enter text on the left hand box to start a search it simply pases 2 parameters:
inputstring = "33129"
Go2 = "Go"
That would be one way to do it, on the other hand, once the request is finished it transforms it into another request, thats more specific. You can search by city state or zip, not both.
If you request with a zip you get redirected to:
http://forecast.weather.gov/MapClick.php?CityName=Miami&state=FL&site=MFL&lat=25.77&lon=-80.2
So there is probably a redirection going on there.
You are going to have to take a close look at how to work with this.
Now, to do a post request in android use a name value pair like this.
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("inputstring","33129));
Ramp's answer shows the rest.
Also, ALL comunication should be done on a thread that is not the main UI thread or you will get a ANR error.
When I checked out your URL, I entered city and state.This is the URL it generates in HTTP POST :
http://forecast.weather.gov/MapClick.php?CityName=Edison&state=NJ&site=PHI&textField1=40.5288&textField2=-74.3693
So your will do a HTTP POST with the CityName and state URL parameters. It will be something like this if you use apache HttpClient in your android program :
( It should be OK to use HTTP GET too I guess)
HttpPost post = new HttpPost(url);//construct url with cityName and State
HttpResponse httpResp = httpClient.execute(post);
StatusLine status = httpResp.getStatusLine();
Hope this helps.
Something like this:
HttpClient hc = new DefaultHttpClient();
List<NameValuePair> l = new ArrayList<NameValuePair>(6);
l.add(new BasicNameValuePair("fieldname", "fieldvalue"));
//More fields...
HttpPost pr = new HttpPost(TheURL);
pr.setEntity(new UrlEncodedFormEntity(l, "the-proper-encoding"));
HttpResponse Resp = hc.execute(pr);
if(Resp.getStatusLine().getStatusCode() != 200)
//Fail...