Consume ASP web service with JSON response on iOS - ios

I am trying to call a web service that is developed with ASP.NET. The purpose is to pass a username and password to the web service to simulate a log-in procedure.
In order to call the service i used the following method:
NSError *errorReturned = nil;
NSString *urlString = #"http:myDomain/myMethod?Operation=SignIn";
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod: #"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:#"test" forKey:#"userName"];
[dict setObject:#"test" forKey:#"passWord"];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:kNilOptions error:&errorReturned];
[request setValue:[NSString stringWithFormat:#"%d", [jsonData length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody: jsonData];
NSURLResponse *theResponse =[[NSURLResponse alloc]init];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&theResponse error:&errorReturned];
if (errorReturned)
{
NSLog(#"%#", errorReturned);
}
else
{
NSString *retVal = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%#", retVal);
}
After running the app and clicking on the UIButton that fires the above method, nothing is shown in the console window.
The service returns the response in JSON format.
I want to know if i am missing something here since i am neither getting an error nor success log?
Any help would be appreciated!
Thank you.
Granit

A couple of thoughts:
If this method is getting called, you'd see something, even if retVal was empty and your
NSLog(#"%#", retVal);
just logged the app name and timestamp. Maybe change that NSLog to
NSLog(#"retVal = %#", retVal);
to remove any ambiguity. Or put in breakpoints in your code and single step through it to see what path the app takes.
Are you confident of your server interface? For example, is it possible that the Operation value of SignIn belongs in the JSON request, itself? Also, some services are case sensitive, so you might want to check that, too.
I don't know what access you have to the server, but it would be worthwhile to check the logs to make sure the request was received, possibly temporarily adding some logging within the code so you can confirm that the parameters were all received properly. Or, if nothing else, make sure that the server properly logs/reports any errors.
BTW, your instantiation of theResponse is unnecessary, and should just be
NSURLResponse *theResponse = nil;
The sendSynchronousRequest call doesn't populate an existing NSURLResponse instance, but rather creates a new instance and updates theResponse to point to it.
You should fix your request first, but you probably want, at the very least, to change this to use sendAsynchronousRequest instead of sendSynchronousRequest. You should never do synchronous calls on the main thread.

I solved my issue by using ASIHHTPRequest. Also i checked the server interface and it turned out that the parameters had to be sent with the URL.
-(void)signInAction:(id)sender{
NSURL *url = [NSURL URLWithString:#"http://mydomaain.com/UserService/SignIn/test/test"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDidFinishSelector:#selector(requestCompleted:)];
[request setDidFailSelector:#selector(requestError:)];
[request setDelegate:self];
[request setRequestMethod:#"GET"];
[request startAsynchronous];
}
- (void)requestCompleted:(ASIHTTPRequest *)request
{
NSString *responseString = [request responseString];
//[responseString UTF8String];
NSLog(#"ResponseString:%s",[responseString UTF8String]);
}
- (void)requestError:(ASIHTTPRequest *)request
{
NSError *error = [request error];
NSLog(#"Error:%#",[error description]);
}

Related

PUT request and Header token

I'm writing some with server API. I'm using RestKit but this question I wrote without. I don't understand why console request is working and my is not. Please help me with this.
-(void)uploadFile {
NSString *URLPath = [NSString stringWithFormat:#"https://api.interlabs.pro/v1/texts/23041/content"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:URLPath]];
[request setHTTPMethod:#"PUT"];
[request addValue: #"Bearer ewogICAgInR5cCI6ICJKV1QiLAogICAgImFsZyI6ICJIUzI1NiIKfQ.ewogICAgImlzcyI6ICJhcGkuaW50ZXJsYWJzLnBybyIsCiAgICAiaWF0IjogMTQ2MzY3ODg2NCwKICAgICJleHAiOiAxNDYzNjgyNDY0LAogICAgInN1YiI6IDgzCn0.SuvGXfsDDzpA5-qJtRUZi7uw98IqA8_axfTGcMVjZdw" forHTTPHeaderField: #"Authorization"];
NSError *err;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSString *resSrt = [[NSString alloc]initWithData:responseData encoding:NSASCIIStringEncoding];
NSLog(resSrt);
}
And it's still doesn't not work, but console work perfectly
But enter link description here
update token link
The code works fine and result is that token is expired.
But you should not use deprecated methods like "NSURLConnection sendSynchronousRequest", then you should check error, when handling results from internet it is utf8 most of the time and not ascii. Then when logging strings use NSLog(#"%#", theString) to avoid problems if the content of theString contains formating specifiers.

Passing a Session ID to a GET Objective-C

So, I have to methods to approach a web service:
A GET:
- (NSDictionary *)getDataFromURL:(NSString*)url {
NSString * serverAddress =[NSString stringWithFormat:url,mySchoolURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL
URLWithString:serverAddress]
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:10
];
[request setHTTPMethod: #"GET"];
NSError *requestError = nil;
NSURLResponse *urlResponse = nil;
NSData *response = [NSURLConnection
sendSynchronousRequest:request
returningResponse:&urlResponse
error:&requestError];
NSError* error = nil;
NSDictionary *output = [NSJSONSerialization JSONObjectWithData:response options:kNilOptions error:nil];
return output;
}
and a POST:
-(NSData*)postData:(NSDictionary*)requestData toUrl:(NSString*)destination {
NSError *error;
NSData *postdata = [NSJSONSerialization dataWithJSONObject:requestData options:0 error:&error];
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[postdata length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:destination,mySchoolURL]]];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postdata];
[request setHTTPMethod:#"POST"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
return nil;
}
Somehow, the HTTP header of the POST method does include the cookie's SessionID, while the GET one doesn't.
I have to admit that I don't fully understand the innards of cookies and the like, but several sources on the web claim that I should't worry about the cookies at all, since they are taken care of automatically.
Anyway, the web service I'm talking to expects a Session ID in both POST and GET situations, so now I'm forced to start understanding what's going on.
Could any of you help me out here?
The concrete question is: how to I pass a Session_ID to a URL using a GET method?
Thanks ahead
Okay so one way to do this is by simply adding the cookies to the HTTP headers. When doing this the correctness of the URL is key. If the protocol is wrong, some cookies may not be included. You will need to get all available cookies, and then create a dictionary for the headers with he available cookies. Then you simply add those headers to your request by calling setAllHTTPHeaderFields:. I placed a quick example of how to do this below, however you can learn more about how cookies work at the Apple Documentation Class Reference
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:request.URL];
NSDictionary *headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
[request setAllHTTPHeaderFields:headers];
I really hope this helps you out. I would recommend reading the Apples Documentation to help you out as much as possible. I wish you the best of luck!

How to connect (GET request) ios app to django rest framework

I came to the last stage of development of my app and here is the bit that I've never done before.
My friend has developed and API for my app to send and receive data, using django rest framework.
I need to authenticate my app to connect to it, send some data and receive data.
What I have found so far is:
NSURL *url = [NSURL URLWithString:#"http://localhost:8080/my/path/to/api/login/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSString *authStr = [NSString stringWithFormat:#"%#:%#", #"myUsername", #"myPassword"];
NSData *authData = [authStr dataUsingEncoding:NSASCIIStringEncoding];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", authData];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
//------------------------------------------------------------------------------------------------------------------------------------//
//EDIT: Added this based on answer form #Quver.
NSURLResponse *response1;
NSError *responseError;
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response1 error:&responseError];
if (result.length > 0 && responseError == nil)
{
NSDictionary *greeting = [NSJSONSerialization JSONObjectWithData:result
options:0
error:NULL];
NSLog(#"Got response form server: %#", greeting);
}
This equals output like:
<0a0a3c68 746d6c3e 0a0a2020 20203c68 6561643e 0a202020 20202020 200a2020 20202020 20200a20 20202020 + ~50 lines of similar stuff. Hope this helps.
//-----------------------------------------------------------------------------------------------------------------------------------------//
I guess this is the way to create request. What should I do next? And how do I know that I have connected?
Then, if I have connected, how do I get data form there? (I have a url that gives me json as output - this is what I want to get). Assume the url to be http://localhost:8080/url/that/gives/json/.
Thank you for any help. Hope this is enough information for the question. I will add anything else required.
NSURLResponse *response;
NSError *responseError;
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&responseError];
Add this to get response. You already prepared request, now it's time to send it with NSURLConnection. I you sync request insted of async, becouse of using GCD for whole metod request + sqlite update.
After a few days of searching I have found a way.
First, we need a token for authentication. I am generating it through terminal for now:
curl -X POST -d "grant_type=password&username=<your username>&password=<your password>" http://<client secret>:<client id>#url/to/token/page
Then, in your view controller where you want to connect:
//always put </> at the end of link
NSURL *aUrl = [NSURL URLWithString: #"http://where/you/trying/to/conect"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:30.0];
[request addValue:[NSString stringWithFormat:#"<type> <your token>"] forHTTPHeaderField:#"Authorization"];
[request setHTTPMethod:#"GET"];
NSError *error = nil;
self.response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error: &error];
This will return any json that the page supposed to return. This might not be the most secure way, but this is exactly what I need for now. I will look at more secure solutions like OAuth 2, later.
Hope this helps to someone.

NSURLConnection sends GET request instead of POST request

I'm trying to make a POST request using NSURLConnection. I use Charles to debug and Charles every time says that the method is GET. I've tried all different ways and can't get it to work. I am NOT using JSON.
-(void)getList
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:#"http://example.com/api/getList"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSString *radius = #"15";
NSString *latitude = #"-117.820833";
NSString *longitude = #"34.001667";
NSString *parameters = [NSString stringWithFormat:#"longitude=%#&latitude=%#&radius=%#", longitude,latitude, radius];
NSLog(#"PARAMS = %#", parameters);
NSData *data = [parameters dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPMethod:#"POST"];
[request setValue:#"text/plain" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:data];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *responseString = [[NSString alloc]initWithData:result encoding:NSUTF8StringEncoding];
NSLog(#"RESULT = %#", responseString);
}
Does anybody know what am I doing wrong? When I access my web service it seems like I'm not posting anything. I'm getting empty response.
Please help with any ideas. I pretty much have to make a simple POST request. Maybe someone can help me debug this better.
If the server is redirecting your request for some reason (perhaps authentication) then the POST information can get lost.

Need example for Posting Core Data objects in JSON to RESTful web service

I've been reading over code samples and posts for days but I haven't found a definitive way to post JSON data from my Core Data objects to a RESTful web service. There's a TON of documentation about pulling the JSON from a web service but not so much about sending stuff back. Can anyone point me to a good example or post some code on how to do it? I'm using Core Data and I have the object I want to send back mapped to a Dictionary but I'm missing the code to send it to the service.
EDIT:
I ended up with the code below which looks right and runs without errors, but I get 0 bytes of data returned and my webservice doesn't seem to be receiving the request. The JSON data looks good, the URL is correct, and I can hit the webservice and get JSON data back from it. The NSURLConnection delegate methods also fire as expected.
Is there anything I'm missing below?
- (void)SubmitSystems
{
NSFetchRequest * allSystems = [[NSFetchRequest alloc] init];
[allSystems setEntity:[NSEntityDescription entityForName:#"System" inManagedObjectContext:self.managedObjectContext]];
NSError * error = nil;
NSArray * systems = [self.managedObjectContext executeFetchRequest:allSystems error:&error];
//error handling goes here
//for (NSManagedObject * system in systems) {
NSManagedObject *system = systems[2];
NSString *entityString = #"System";
NSString * serverString = [NSString stringWithFormat:#"%#%#", kWebServiceAddress, entityString];
NSURL *url = [NSURL URLWithString:serverString];
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:[self jsonSystemDictionary:(System *)system] options:kNilOptions error:&error];
//NSLog([[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]); //debug only
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy: NSURLRequestReloadIgnoringCacheData timeoutInterval: 30.f];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:[NSString stringWithFormat:#"%d", [jsonData length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody: jsonData];
self.urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
//}
}
You're going to need to NSMutableURLRequest. Using this, you can use setHTTPMethod and pass it the #"POST" string, and then use the attributes of your NSManagedObject to populate the URL, HTTPBody and/or HTTPHeader as needed.

Resources