Xcode https call to Restful API - ios

I am having an issue in making a call to our RESTful API. The request is to get the token from the API; I need that token to use it to make further calls on that API.
The issue is that whenever I make that call, I get HTTP 403 status code and I don't know why. I am making the same calls from Android but they work fine without any issue.
Actually I have no experience at all to work with xCode; I am just implementing some changes in the existing code which was written by some other developer. I don't know if I am doing something wrong or what.
id keys[] = {#"grant_type", #"client_id", #"client_secret", #"username", #"password"};
id objects[] = {#"password", #"AppClientID", #"AppClientSecret", #"usernamehere", #"userpasswordhere"};
NSUInteger count = sizeof(objects) / sizeof(id);
NSDictionary *d = [NSDictionary dictionaryWithObjects:objects forKeys:keys count:count];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:d options:NSJSONWritingPrettyPrinted error:nil];
NSURL *url = [NSURL URLWithString:#"https://oauth-test.websitename.com/token"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"Basic" forHTTPHeaderField:#"Authorization"];
[request setHTTPBody:jsonData];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response,
NSData *data, NSError *connectionError) {
if(data.length > 0 && connectionError == nil) {
NSLog(#"Response --> %# ", response);
}
}
];
Can someone try to help me figure out what is actually going wrong?
Thanks in advance.

I ran your code and the log, i am getting is
Error Domain=NSURLErrorDomain Code=-1003 "A server with the specified
hostname could not be found." UserInfo=
{NSUnderlyingError=0x608000059aa0 {Error Domain=kCFErrorDomainCFNetwork
Code=-1003 "A server with the specified hostname could not be found."
UserInfo={NSErrorFailingURLStringKey=http://oauth-
test.websitename.com/token, NSErrorFailingURLKey=http://oauth-
test.websitename.com/token, _kCFStreamErrorCodeKey=8,
_kCFStreamErrorDomainKey=12, NSLocalizedDescription=A server with the
specified hostname could not be found.}},
NSErrorFailingURLStringKey=http://oauth-test.websitename.com/token,
NSErrorFailingURLKey=http://oauth-test.websitename.com/token,
_kCFStreamErrorDomainKey=12, _kCFStreamErrorCodeKey=8,
NSLocalizedDescription=A server with the specified hostname could not
be found.}
I tried it with NSUrlSession also but it is giving same problem.
I think your server is not configured
Below is the code with URL session
id keys[] = {#"grant_type", #"client_id", #"client_secret",
#"username", #"password"}; id objects[] = {#"password", #"AppClientID", #"AppClientSecret", #"usernamehere", #"userpasswordhere"};
NSUInteger count = sizeof(objects) / sizeof(id); NSDictionary *d = [NSDictionary dictionaryWithObjects:objects forKeys:keys count:count];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:d options:NSJSONWritingPrettyPrinted error:nil];
NSURL *url = [NSURL URLWithString:#"http://oauth-test.websitename.com/token"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"Basic" forHTTPHeaderField:#"Authorization"]; [request setHTTPBody:jsonData];
NSURLSession * session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionDownloadTask *dataTask = [session downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(#"%#", response);
}];
[dataTask resume];

Related

Request is blank when sending data through iOS to google cloud endpoint

i am working on Google cloud endpoint with datastore. When i am passing data through Android & iOS with method POST , it is getting saved in datastore with empty record. i.e. request is properly working but the way i am sending data is wrong. please help me for this.
For iOS, code is mentioned below :
NSDictionary *headers = #{ #"content-type": #"application/json",
#"cache-control": #"no-cache",
#"postman-token": #"404012ff-722e-c5d8-48db-fa7fb3260841"};
NSLog(#"header %#",headers);
request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"enter url here..."]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
NSString* strRequest=#"";
strRequest =[[NSString alloc] initWithFormat:#"displayEmail=%#&displayName=%#",#"sonal#gmail.com",#"sonal"];
NSLog(#"url is %# parameter = %#", request , strRequest);
[request setHTTPMethod:#"POST"];
[request setHTTPBody: [strRequest dataUsingEncoding:NSUTF8StringEncoding]];
[request setAllHTTPHeaderFields:headers];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *responseBody = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"responce Body===>%#",responseBody);
if (error) {
NSLog(#"%#", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(#"responce%#", httpResponse);
}
}];
[dataTask resume];
You need to set the httpBody property of your request. If you don't provide a body for the POST, of course it's blank.
https://developer.apple.com/reference/foundation/nsmutableurlrequest/1409064-httpbody
Or Objective-C
https://developer.apple.com/reference/foundation/nsmutableurlrequest/1409064-httpbody?language=objc
We got a solution..
we changed the way of passing data..
here is code :
request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:syncURL]
cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
NSData *requestData = [NSData dataWithBytes:[serverSyncAPIRequestJSON UTF8String] length:[serverSyncAPIRequestJSON length]];[request setHTTPMethod:#"POST"]; [request setHTTPBody:requestData]; [request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];

POST method resulting status code 400 ios

I have tried many times, but i cant do a simple POST request to a remote API.. I need to post username and password to get a login authorization. Here are the code:
NSURL * url = [NSURL URLWithString:#"http://thapi.xyz/auth/login"];
NSString *postData = #"username=emailExample#gmail.com&password=123456";
NSData * dataBody = [postData dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *postLenght = [NSString stringWithFormat:#"%d",[dataBody length]];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-unlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:postLenght forHTTPHeaderField:#"Content-Lenght"];
[request setHTTPBody:dataBody];
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
NSLog(#" ERROR %#, RESPONSE %# AND DATA %#",connectionError,response,[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
}];
I have made another version, witch uses NSDictionary and Json parsing (the API uses json)
NSDictionary * login = #{#"username":#"exampleMail#gmail",#"password":#"123456"};
NSData * jsonData = [NSJSONSerialization dataWithJSONObject:login options:NSJSONWritingPrettyPrinted error:nil];
NSString *postLenght = [NSString stringWithFormat:#"%d",[jsonData length]];
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-unlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:postLenght forHTTPHeaderField:#"Content-Lenght"];
[request setHTTPBody:jsonData];
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
NSLog(#" ERROR %#, RESPONSE %# AND DATA %#",connectionError,response,[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]);
}];
And here is the result of both codes:
2016-06-18 05:24:20.329 Hoffmann iOS[10317:1088208]
ERROR (null), RESPONSE <NSHTTPURLResponse: 0x796bee60>
{ URL: http://thapi.xyz/auth/login } { status code: 400, headers {
"Access-Control-Allow-Origin" = "*";
Connection = "keep-alive";
"Content-Length" = 70;
"Content-Type" = "application/json; charset=utf-8";
Date = "Sat, 18 Jun 2016 04:24:18 GMT";
Etag = "W/\"46-22Kcj8zTKrWgQ7OCr429+w\"";
Server = "nginx/1.6.2";
Vary = "Accept-Encoding";
"X-Powered-By" = undefined;
"X-Response-Time" = "5.357ms";
} } AND DATA {"name":"ParameterError","message":"Request should contain: username"}
I really appreciate all answers, and sorry for my bad english...
Perhaps the misspelling of the header variable is the issue ("Content-Lenght" is misspelled):
[request setValue:postLenght forHTTPHeaderField:#"Content-Length"];
NSURLConnection is deprecated. use nsurlsession instead Try this code....
//replace the following code with your request params
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *clientSessionId = [prefs stringForKey:#"clientSession"];
NSString *bodyString = [NSString stringWithFormat:#"[\"%#\",{\"session_token\":\"%#\",\"request\":[\"GetUnitDetails\",{}]}]",clientSessionId,clientSessionId];
//Make mutable url request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[Settings getMobileUrl]]];
NSData *postData = [bodyString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
[request setHTTPBody:postData];
//Change the http method as per your own choice
[request setHTTPMethod:#"POST"];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[postData length]];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data,NSURLResponse *response,NSError *connectionError)
{
if ([data length] > 0 && connectionError == nil)
{
NSError *localError = nil;
self.parsedObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:&localError];
NSString* unitResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSData *jsonData = [unitResponse dataUsingEncoding:NSUTF8StringEncoding];
NSMutableArray *jsonDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:nil];
}else {
NSLog(#"No response received");
}
}]resume];
You could try using a NSDictionary for the parameters. The following will send the parameters correctly to a JSON server.
NSError *error;
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURL *url = [NSURL URLWithString:#"http://thapi.xyz/auth/login"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPMethod:#"POST"];
NSDictionary *login = [[NSDictionary alloc] initWithObjectsAndKeys: #"username":#"exampleMail#gmail",#"password":#"123456",
nil];
NSData *postData = [NSJSONSerialization dataWithJSONObject:login options:0 error:&error];
[request setHTTPBody:postData];
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
}];
[postDataTask resume];
Hope this works Properly...:)
try also to correct "setValue:postLenght", since I guess that doesn't exist, and will probably set Content-Length to 0.

Objective c post request not sending the data

Good day.Im trying to send simple post data to server.This is the code how i do it.
-(void)makeRequest:(NSString*)stringParameters{
NSError *error;
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURL *url = [NSURL URLWithString:#"http://vaenterprises.webatu.com/Authentication.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[request addValue:#"application/text" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"application/text" forHTTPHeaderField:#"Accept"];
[request setHTTPMethod:#"POST"];
NSString* postData = #"tag=hello&username=yo&something=something";
[request setHTTPBody:postData];
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
[self parseJson:data];
}];
[postDataTask resume];
}
It looks great till i echo the whole post from php side like this
echo json_encode($_POST);
and i print the result in the iOS like this
-(void)parseJson:(NSData*) data{
NSString *myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError *jsonError = nil;
NSDictionary* jsonObject= [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
NSLog(#"%#",myString);
}
this issue is that i get empty string..so it means that post data not being send and that is 10000 percent objective c side issue and i have no clue why its so as in this method we only got setHttpBody with the actual string which contains key and value separated by & but that data not being send as you can see.So what am i doing wrong?Please tell somebody
Http body has to be of type NSData. Try out following code
NSString* stringData = #"tag=hello&username=yo&something=something";
NSData* data = [stringData dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:data];

cancel NSURLConnection in ios

I am calling webservice on mapView drag/regionChange. I want to keep some delay in the web service calls. So I want that whenever the user drags the map multiple times, all previous web service calls should be cancelled and only last drag web service call should be fired.
How do I do this?
Following is my code:
{ .... NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
NSString *postLength = [NSString stringWithFormat:#"%lu",(unsigned long)[data length]];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:data];
[request setHTTPMethod:#"POST"];
NSMutableDictionary __block *dictResponse;
[[NSOperationQueue mainQueue] cancelAllOperations];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if(connectionError == nil){
dictResponse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&connectionError];
}
You cannot cancel a sendAsynchronousRequest. If you used a delegate-based NSURLConnection request, then you could cancel it, but (a) that's more coding than you probably want to bother with; (b) NSURLConnection is deprecated, so you should be NSURLSession anyway; and (c) NSURLSession allows you to cancel the task using the NSURLSessionTask reference that is returned to you:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPBody:data];
[request setHTTPMethod:#"POST"];
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(#"connection error = %#", error);
return;
}
NSError *parseError;
NSDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&parseError];
if (!responseObject) {
NSLog(#"parse error = %#", parseError);
}
dispatch_async(dispatch_get_main_queue(), ^{
// use response here; e.g., updating UI or model objects
});
}];
[task resume];
If you need to cancel this request, just call [task cancel]. So save this NSURLSessionTask in some weak variable if you want to keep track of it and cancel it later.
Don't use the sendAsynchronousRequest convenience API, use the main delegate API so you have access to the instance of NSURLConnecyion to call cancel on.
Also, don't cancel operations on the main queue, you don't know what's there, and consider using NSURLSession

Difficulty receiving JSON from GET request using NSURLConnection

I'm having a hard time trying to receive JSON form a NSURLConnection request. Can anybody offer any advice? I can't understand why the JSON does not appear
EDIT: When I append the endpoint /books to the end of the url string I get this JSON response: " json NSDictionary * 0 key/value pairs. " Does this mean that there is nothing in the server?
-(void)makeLibraryRequests
{
NSURL *url = [NSURL URLWithString:#"http://prolific-interview.herokuapp.com/54bexxxxxxxxxxxxxxxxaa56"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; //;]cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:20.0f];
[request setHTTPMethod:#"GET"];
// This is actually how jQuery works. If you don't tell it what to do with the result, it uses the Content-type to detect what to do with it.
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
//[request setValue:#"application/json; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc]init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
//parse data here!!
NSError *jsonError;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
if (json) {
//NSArray *allBooks = [json objectForKey:#"books"];
//create your MutableArray here
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
else{
NSLog(#"error occured %#", jsonError);
NSString *serverResponse = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"\n\nError:\n%#\n\nServer Response:\n%#\n\nCrash:", jsonError.description, serverResponse);
//[NSException raise:#"Invalid Data" format:#"Unable to process web server response."];
}
}];
}
As YiPing pointed out, you must provide the books end point. But you won't have anything there until you first post a book.
NSDictionary *params = #{#"author": #"Diego Torres Milano",
#"categories" : #"android,testing",
#"title": #"Android Application Testing Guide",
#"publisher": #"Packt Publishing",
#"lastCheckedOutBy": #"Joe"};
NSURL *url = [NSURL URLWithString:#"http://prolific-interview.herokuapp.com/54bexxxxxxxxxxxxxaa56/books/"]; // your id removed for security's sake ... put it back in
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSError *encodeError;
NSData *body = [NSJSONSerialization dataWithJSONObject:params options:0 error:&encodeError];
NSAssert(body, #"JSON encode failed: %#", encodeError);
request.HTTPBody = body;
So, first POST a book using a request like the above, then your original GET (assuming you add the end point) will now return a result.
Add some endpoints to your URL
try this:
http://prolific-interview.herokuapp.com/54bexxxxxxxxxxxxxxxxaa56/books/

Resources