AFHTTPClient putpath method - ios

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

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 :)

How to call a function in Microsoft Dynamics NAV to retrieve XML using AFNetworking2

I am an experienced iOS developer but have very basic knowledge of SOAP and various HTTP protocols.
I have a client who has created a Microsoft Dynamics NAV interface that will serve me some XML for an iOS app. I am using AFNetworking2 for the networking side and using NSXMLParser to parse the XML.
The parser works fine but I am struggling to get the XML data from the clients NAV url.
I believe I have successfully authenticated against the server but I can't seem to call the function that will return XML data for me.
I currently use this code to authenticate:
AFHTTPRequestOperationManager *manager= [AFHTTPRequestOperationManager manager];
NSURLCredential *credential = [NSURLCredential credentialWithUser:[AppController sharedAppController].authUserName
password:[AppController sharedAppController].authPassword
persistence:NSURLCredentialPersistenceForSession];
NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:#"POST"
URLString: #"http://xxx.xxx.xx.x:7056/DynamicsNAV_KPI/WS/Retail%20Company/Codeunit/Kiwi_KPI"
parameters:nil
error:nil];
manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
[manager.requestSerializer setValue:#"application/xml" forHTTPHeaderField:#"Accept"];
[manager.requestSerializer setValue:#"application/xml" forHTTPHeaderField:#"Content-Type"];
AFHTTPRequestOperation *authenticationOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[authenticationOperation setCredential:credential];
[authenticationOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Authorisation Success!");
NSLog(#"Response XML: %#", [operation responseString]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Authentication Failure: %#", error);
}];
This seems to get me in the door as the Authorisation success! message appears in the log. I am told by my client I now need to call the “GetData_KPI” with two parameters: “user” (SERVER\username) and an empty object/variable that should hold your return xml.
I created a what I believed was a SOAP Message for this:
NSString *soapMessage = [NSString stringWithFormat:#"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<soap:Envelope\n"
"xmlns:c=\"http://schemas.xmlsoap.org/soap/encoding/\"\n"
"xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"\n"
"xmlns:n1=\"urn:microsoftdynamicsschemas/codeunit/Kiwi_KPI\">\n"
"<soap:Header></soap:Header>"
"<soap:Body>"
"<n1:GetDATA_KPI id=\"o0\" c:root=\"1\">"
"<n1:user>SERVER\\jdoe</n1:user>"
"<n1:kPIxml></n1:kPIxml>"
"</n1:GetData_KPI>"
"</soap:Body>"
"</soap:Envelope>"];
And added these 2 lines of code:
[request setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
[request addValue:soapMessage forHTTPHeaderField:#"SOAPAction"];
But when these 2 lines are added the authentication doesn't work and I get an error like this:
Authentication Failure: Error Domain=com.alamofire.error.serialization.response Code=-1011 "Request failed: unsupported media type (415)" UserInfo=0x188635f0 {com.alamofire.serialization.response.error.response=<NSHTTPURLResponse: 0x177ba0f0> { URL: http://xxx.xxx.xx.xx:7056/DynamicsNAV_KPI/WS/Retail%20Company/Codeunit/Kiwi_KPI } { status code: 415, headers {
"Content-Length" = 0;
Date = "Tue, 16 Jun 2015 21:19:55 GMT";
Server = "Microsoft-HTTPAPI/2.0";
} }, NSErrorFailingURLKey=http://xxx.xxx.xx.x:7056/DynamicsNAV_KPI/WS/Retail%20Company/Codeunit/Kiwi_KPI, NSLocalizedDescription=Request failed: unsupported media type (415), com.alamofire.serialization.response.error.data=<>}
My questions are:
1. How do I call the function GetDataKPI using AFNetworking?
How should the SOAP message be constructed to pass user name a nd a blank parameter for XML?
How will I access the blank parameter to get XML?
I really am at a loss with this stuff and would really appreciate any help.
Well I can only help you with one part of the question. As I can see your client used standard feature of Nav 2009 (or older) - web services.
Let's assume you have authorized successfully. Would get http 401 otherwise.
Next. Unsuported media... dunno what this is, but you can test weather your SOAP message is valid using any app that can post soap, like soapUI (see this answer). It will also help you create and send propper message by consuming wsdl of Nav web service. So you will see both request and response in xml format. If you end up getting http 500 see this answer.
How do I call the function GetDataKPI using AFNetworking?
That I can not help you with.
How should the SOAP message be constructed to pass user name and a blank parameter for XML?
Use sopaUI to build valid soap(xml) request. No such thing as blank parameter needed afaik. It is defined as output xml parameter in Nav but for you it will be just soap(xml) resposnse which you will get.
How will I access the blank parameter to get XML?
Parse HTTP response of your AFNetworking2 whatever this thing is =) Can only gues that it will be somwhere in responseObject.
If nothing helps try posting your web services wsdl here. May be it will clear things up.

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.

Having problems integrating with SimpleUPC API on 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.

Simple RestKit login without using JSON

It's been two days that I'm looking for a simple code for RestKit API for logging into a website without using JSON. Here is the code that I wrote so far:
- (void)login
{
[RKClient clientWithBaseURLString:#"http://Mywebsite.com/login.php"];
NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObject:#"user" forKey:#"username"];
[params setObject:#"pass" forKey:#"password"];
[params setObject:#"login" forKey:#"type"];
[[RKClient sharedClient] post:#"/login" params:params delegate:self];
}
- (void)request:(RKRequest*)request didLoadResponse:(RKResponse*)response
{
NSLog(#"HTTP status code: %d", response.statusCode);
NSLog(#"HTTP status message: %#", [response localizedStatusCodeString]);
}
- (void)objectLoader:(RKObjectLoader*)objectLoader didFailWithError:(NSError*)error {
NSRange range = [[error localizedDescription] rangeOfString:#"-1012"];
if (range.length > 0){
//Do whatever here to handle authentication failures
}
RKLogError(#"Hit error: %#", error);
}
Here is the log that I receive:
2012-09-08 21:44:14.633 RestKitTest[889:fb03] I restkit:RKLog.m:33 RestKit initialized...
2012-09-08 21:44:15.010 RestKitTest[889:fb03] I restkit.network.reachability:RKReachabilityObserver.m:369 Network availability has been determined for reachability observer <RKReachabilityObserver: 0x6c5a560 host=0.0.0.0 isReachabilityDetermined=YES isMonitoringLocalWiFi=NO reachabilityFlags=-R -----l->
2012-09-08 21:44:21.021 RestKitTest[889:fb03] I restkit.network:RKRequest.m:676 Status Code: 404
2012-09-08 21:44:21.036 RestKitTest[889:fb03] HTTP status code: 404
2012-09-08 21:44:21.090 RestKitTest[889:fb03] HTTP status message: not found
Any idea how I can fix this issue would be appreciated.
I'd say it 404s because you set baseURL as http://Mywebsite.com/login.php yet you POST as post:#"/login". Do you really want to access http://Mywebsite.com/login.php/login?
The baseURL should be set to a common prefix to all your backend calls, in your case http://Mywebsite.com, the resource itself should be posted as post:#"/login.php". The resource name and baseURL are concatenated before the request is sent.
You'll need to provide info on what login.php is doing. I don't see why it should 404 if the script url resolves correctly.
Also, if that PHP script does a redirect on success, you should use the RKClient method post:usingBlock: and inside that block do request.followRedirect = NO;. That way you'll get the correct status code, if you are returning one.
If may also help to log more of the response:
NSLog(#"Header fields: %#", response.allHeaderFields);
NSLog(#"Body: %#", response.bodyAsString);

Resources