iOS Check for Token - ios

I'm making an app that requires you to login in. I"m using JSON. So far I've been able send a POST request with the Username and Password and I get a token back (it shows up in the console). When I don't enter in the correct username/password combination, I don't get a token back. What I would like to happen is to proceed to the next view controller if I get a token back. I think that I need to use an if statement (I'll put the code for switching view controllers into it) but I don't know what parameters I need in order to check if I get a token back.
Here is the code I'm using in the implementation file. It is in a method that runs when a button is pressed:
#try {
if([[usernameTextField text] isEqualToString:#""] || [[passTextField text] isEqualToString:#""] ) {
[self alertStatus:#"Please enter both Username and Password" :#"Login Failed!"];
} else {
NSString *post =[[NSString alloc] initWithFormat:#"username=%#&password=%#",[usernameTextField text],[passTextField text]];
NSLog(#"PostData: %#",post);
NSURL *url=[NSURL URLWithString:#"https://beta.network360.com/tokens"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"Response code: %d", [response statusCode]);
if ([response statusCode] >=200 && [response statusCode] <300)
{
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(#"Response ==> %#", responseData);
SBJsonParser *jsonParser = [SBJsonParser new];
NSDictionary *jsonData = (NSDictionary *) [jsonParser objectWithString:responseData error:nil];
NSLog(#"%#",jsonData);
NSInteger success = [(NSNumber *) [jsonData objectForKey:#"success"] integerValue];
NSLog(#"%d",success);
if(success == 1)
{
NSLog(#"Login SUCCESS");
[self alertStatus:#"Logged in Successfully." :#""];
} else {
NSString *error_msg = (NSString *) [jsonData objectForKey:#"error_message"];
[self alertStatus:error_msg :#"Login Failed!"];
}
} else {
if (error) NSLog(#"Error: %#", error);
[self alertStatus:#"Connection Failed" :#""];
}
}
}
#catch (NSException * e)
{
NSLog(#"Exception: %#", e);
[self alertStatus:#"Login Failed." :#""];
//[[PSearchViewController new] performSegueWithIdentifier:#"loginCancel" sender:self];
}
Also, here is what I get in the console output when I put in the correct username/password combination (BTW I tried to change all the stuff that showed up in the console that was confidential, so if some stuff doesn't quite match, it should be fine. I just wanted to show that I get a token back):
2013-07-28 13:23:21.607 Empyrean[28283:c07] PostData: username=username#gmail.com&password=password
2013-07-28 13:23:22.300 Empyrean[28283:c07] Response code: 200
2013-07-28 13:23:22.301 Empyrean[28283:c07] Response ==> {"token":"scFDzxSAVk2sxQBShEGS","user":{"id":300230,"username":"username#gmail.com","display_name":"FirstName LastName","unconfirmed_email":null,"email":"username#gmail.com","confirmation_email":"username#gmail.com","client_identifier":null,"client_id":138,"is_admin":false,"support_email":"support#supportemail.com","application_name":"AppName","show_project_vintage_date":false,"is_anonymous":false,"is_active":true,"is_confirmed":true,"pending_reconfirmation":false,"can_resend_confirmation":false,"client_name":"Broker","show_advertisements":true,"header_logo":"/foo/headerlogo.gif","report_footer_logo":"/stuff/foo/footerlogo.png","authorized_features":["find_stuff","do_stuff","stuff_stuff","settings","menu","manage_stuff","measure_stuff","export_stuff"],"url":"https://www.website.com/stuff/numbersdsjkflds"}}
2013-07-28 13:23:22.304 Empyrean[28283:c07] {
token = dlsfkasdfDfdsklfdDsa;
user = {
"application_name" = "Application Name";
"authorized_features" = (
"find_stuff",
"do_stuff",
"stuff_stuff",
settings,
menu,
"manage_stuff",
"measure_stuff",
"export_stuff"
);
"can_resend_confirmation" = 0;
"client_id" = 138;
"client_identifier" = "<null>";
"client_name" = Broker;
"confirmation_email" = "username#gmail.com";
"display_name" = "FirstName LastName";
email = "username#gmail.com";
"url" = "https://www.website.com/stuff/numbersdsjkflds";
"header_logo" = "/foo/headerlogo.gif";
id = 300230;
"is_active" = 1;
"is_admin" = 0;
"is_anonymous" = 0;
"is_confirmed" = 1;
"pending_reconfirmation" = 0;
"report_footer_logo" = "/stuff/foo/footerlogo.png";
"show_advertisements" = 1;
"show_project_vintage_date" = 0;
"support_email" = "support#supportemail.com";
"unconfirmed_email" = "<null>";
username = "username#gmail.com";
};
}

NSDictionary *jsonData is a dictionary. Therefore, you can see if the token key exists.
if (jsonData[#"token"])
{
// Token exists, so move on.
[self.navigationController pushViewController:nextController animated:YES];
}
else
{
// Tell the user they messed it up.
}

Related

Disqualify lead in Dynamics CRM (iOS)

How can i disqualify lead in Microsoft Dynamics CRM ? Is there any particular API for doing this from iOS platform?
I tried this :
for (id key in [details allKeys]) {
if([key isEqualToString:#"LeadState"])
{
[contactPostDict setObject:#"2" forKey:#"State"];
}
else if([key isEqualToString:#"LeadStatus"])
{
[contactPostDict setObject:#"6" forKey:#"Status"];
}
}
This is the error:
"error": {
"code": "", "message": {
"lang": "en-US", "value": "Error processing request stream. The property name 'Status' specified for type 'Microsoft.Crm.Sdk.Data.Services.Lead' is not valid."
}
}
I have never worked on the iOS platform but from the error that is being thrown, the error seems to be pretty straight forward.
You are looking for the keys "Status" & "State" but they don't exist. Instead you should be looking at their schema names which is as follows
Status = statuscode, State = statecode
Can you try modifying the code to use the above keys and see if you still gets the same error.
(BOOL)setLeadStatus:(NSString *)ID andDetails:(NSMutableDictionary *)details
{
NSString *uri = [MSDYNAMICS_AUTHENTICATION_CALL stringByAppendingPathComponent:[NSString stringWithFormat:#"LeadSet(guid'%#')/",ID]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:uri]];
request.HTTPMethod = #"MERGE";
[request setValue:JSON_CONTENT_TYPE_PARAMETER forHTTPHeaderField:#"Content-Type"];
[request setValue:JSON_CONTENT_TYPE_PARAMETER forHTTPHeaderField:#"Accept"];
NSMutableDictionary *contactPostDict=[[NSMutableDictionary alloc]init];
for (id key in [details allKeys]) {
if([key isEqualToString:#"LeadState"])
{
[contactPostDict setObject:#"2" forKey:#"statecode"];
}
else if([key isEqualToString:#"LeadStatus"])
{
[contactPostDict setObject:#"6" forKey:#"statuscode"];
}
}
NSError *err;
NSData *postData=[NSJSONSerialization dataWithJSONObject:contactPostDict options:NSJSONWritingPrettyPrinted error:&err];
NSString* postString = [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding];
//NSString *postString = #"";
[request setValue:JSON_CONTENT_TYPE_PARAMETER forHTTPHeaderField:CONTENT_TYPE_PARAMETER];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]];
SURLConnection *conn = [[SURLConnection alloc] init];
NSData *responseData = [conn sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *err1 = [[NSString alloc]initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"error: %#",err1);
if(responseData.length==0 && [conn.response statusCode] == 204)
{
[self getLeadDetailsForID:ID];
return YES;
}
else{
NSString *err = [[NSString alloc]initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"error: %#",err);
}
return NO;
}

Google OAuth Suddenly Not Working AFNetworkingErrorDomain

This past week the Google OAuth portion of my iOS app has completely stopped working out of nowhere. The user enters their details into the custom login field within the app, which then authorizes with Google, creates a token, and should tell them that their login has been successful (within the app). Instead, they are seeing a Login Failed message. I cannot seem to figure out why (did Google change something??) but the error code I am getting when users try to login is the following:
2013-10-27 12:49:56.137 XXXX [1210:1a003] URL is https://accounts.google.com/o/oauth2/approval?as=1e543c0fe20b1da5&hl=en_GB&pageId=none&xsrfsign=APsBz4gAAAAAUm1LHD2mXAhs8QexAFwlf9KVIt5UdNj_
2013-10-27 12:49:57.776 XXXX[1210:1a003] 333
2013-10-27 12:49:57.776 XXXX[1210:1a003] Failed: -1011
2013-10-27 12:49:57.777 XXXX[1210:1a003] Description: Error
Domain=AFNetworkingErrorDomain Code=-1011 "Expected status code in (200-299), got 400"
UserInfo=0x96b5700 {NSLocalizedRecoverySuggestion=<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML
4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title>Google
Accounts</title><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta
name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-
scale=1, user-scalable=0" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><link
rel='stylesheet' type='text/css' href='https://ssl.gstatic.com/accounts/o/1893590695-error_page_css_ltr.css'>
<script type="text/javascript" src="https://ssl.gstatic.com/accounts/o/708588620-common_lib.js"></script>
<style>#media screen and (max-width:500px) {#robot {background: none; min-height: 0; min-width: 0; padding: 0;}#stack_trace {display: none;}}
#oauth2_request_info_header {background-image: url("https://ssl.gstatic.com/accounts/o/blank.gif");}</style></head><body ><div id="robot"></div><img src="//www.google.com/images/logo_sm.gif" alt="Google"><p class="large"><b>400.</b> <ins>That's an error.</ins></p><p class="large">The page that you requested is invalid. <ins>That's all we know.</ins></p></body></html>, AFNetworkingOperationFailingURLRequestErrorKey=<NSMutableURLRequest https://accounts.google.com/o/oauth2/approval?as=1e543c0fe20b1da5&hl=en_GB&pageId=none&xsrfsign=APsBz4gAAAAAUm1LHD2mXAhs8QexAFwlf9KVIt5UdNj_>, NSErrorFailingURLKey=https://accounts.google.com/o/oauth2/approval?as=1e543c0fe20b1da5&hl=en_GB&pageId=none&xsrfsign=APsBz4gAAAAAUm1LHD2mXAhs8QexAFwlf9KVIt5UdNj_, NSLocalizedDescription=Expected status code in (200-299), got 400, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x96aae40>}
Here are the parts of the code that seem to be causing the error:
-(void)doSignInStep2:(NSString*)response
{
// NSLog(#"RESPONSE: %#", response);
NSString *form = [response substringFromIndex:[response rangeOfString:#"form "].location];
form = [form substringToIndex:[form rangeOfString:#"</form>"].location];
NSString *formAction = [form substringFromIndex:[form rangeOfString:#"action="].location + 8];
formAction = [formAction substringToIndex:[formAction rangeOfString:#"\""].location];
if ([formAction rangeOfString:#"'"].location != NSNotFound)
{
formAction = [formAction substringToIndex:[formAction rangeOfString:#"'"].location];
}
formAction = [formAction stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
//get all input elements in the form
NSMutableArray *elements = [[NSMutableArray alloc] init];
NSRange rng = [form rangeOfString:#"<input "];
while (rng.location != NSNotFound)
{
NSString *inputItem = [form substringFromIndex:rng.location];
NSInteger *inputItemLength = [inputItem rangeOfString:#">"].location + 1;
inputItem = [inputItem substringToIndex:inputItemLength];
NSString *elementName = nil;
NSString *elementValue = nil;
NSRange iiRange = [inputItem rangeOfString:#"name=\""];
if (iiRange.location != NSNotFound) {
elementName = [inputItem substringFromIndex:iiRange.location + 6];
elementName = [elementName substringToIndex:[elementName rangeOfString:#"\""].location];
}
iiRange = [inputItem rangeOfString:#"value=\""];
if (iiRange.location != NSNotFound) {
elementValue = [inputItem substringFromIndex:iiRange.location + 7];
elementValue = [elementValue substringToIndex:[elementValue rangeOfString:#"\""].location];
elementValue = [elementValue stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
}
if (elementName && elementValue) {
NSString *encodedstring = (__bridge NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(__bridge CFStringRef)elementValue,
NULL,
(CFStringRef)#"!*'();:#&=+$,/?%#[]",
kCFStringEncodingUTF8);
if (![elementName isEqualToString:#"submit_access"])
[elements addObject:[NSMutableArray arrayWithObjects:elementName, encodedstring, nil]];
}
form = [form substringFromIndex:rng.location];
form = [form substringFromIndex:inputItemLength];
rng = [form rangeOfString:#"<input "];
}
[elements addObject:[NSMutableArray arrayWithObjects:#"submit_access", #"true", nil]];
NSString *params = #"";
for (int i = 0; i < [elements count]; i++)
{
NSMutableArray *element = [elements objectAtIndex:i];
if ([params length] > 0)
params = [params stringByAppendingString:#"&"];
params = [params stringByAppendingString:[element objectAtIndex:0]];
params = [params stringByAppendingString:#"="];
params = [params stringByAppendingString:[element objectAtIndex:1]];
}
//NSLog(#"Params: %#", params);
NSURL *url = [NSURL URLWithString:formAction];
NSLog(#"URL is %#", url);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
//[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
//[request setValue:[params length] forHTTPHeaderField:#"Content-Length"];
AFHTTPRequestOperation *op3 = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[op3 setCompletionBlockWithSuccess: ^(AFHTTPRequestOperation *operation, NSError *error) {
NSString *response = [[NSString alloc] initWithData:operation.responseData encoding:NSUTF8StringEncoding];
[self doSignInStep3:response];
}failure: ^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"333");
NSLog(#"Failed: %d", error.code);
NSLog(#"Description: %#", error.description);
//NSLog(#"Response: %#", [[NSString alloc] initWithData:operation.responseData encoding:NSUTF8StringEncoding]);
[self.delegate finishedSignIn:[NSNumber numberWithBool:NO] response:nil];
}];
[op3 start];
}
and...
-(void)doSignInStep3:(NSString*)response
{
//NSLog(#"Response: %#", response);
//<input id="code" type="text" readonly="readonly" value="4/Zvd-PjWHw53BqdSzExYus1MsT9dx.snLL4gUE1cocOl05ti8ZT3bZAne4dgI"
if ([response rangeOfString:#"<input id=\""].location == NSNotFound)
{
[self.delegate finishedSignIn:[NSNumber numberWithBool:NO] response:nil];
}
else
{
NSString *code = [response substringFromIndex:[response rangeOfString:#"<input id=\""].location];
code = [code substringFromIndex:[code rangeOfString:#"value=\""].location + 7];
code = [code substringToIndex:[code rangeOfString:#"\""].location];
NSURL *url = [NSURL URLWithString:#"https://accounts.google.com/o/oauth2/token"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData];
[request setHTTPMethod:#"POST"];
//NSLog(#"Code: %#", code);
NSString *params = [NSString stringWithFormat:#"code=%#", code];
params = [params stringByAppendingString:[NSString stringWithFormat:#"&client_id=%#", client_id]];
params = [params stringByAppendingString:[NSString stringWithFormat:#"&client_secret=%#", client_secret]];
params = [params stringByAppendingString:#"&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob"];
params = [params stringByAppendingString:#"&grant_type=authorization_code"];
//params = [params stringByAppendingString:#"&approval_prompt=force"];
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
AFHTTPRequestOperation *op4 = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[op4 setCompletionBlockWithSuccess: ^(AFHTTPRequestOperation *operation, NSError *error) {
NSString *response = [[NSString alloc] initWithData:operation.responseData encoding:NSUTF8StringEncoding];
//NSLog(#"Response: %#", response);
[self processResponse:response];
[self.delegate finishedSignIn:[NSNumber numberWithBool:YES] response:response];
}failure: ^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"444");
NSLog(#"Failed: %d", error.code);
NSLog(#"Description: %#", error.description);
//NSLog(#"Response: %#", [[NSString alloc] initWithData:operation.responseData encoding:NSUTF8StringEncoding]);
[self.delegate finishedSignIn:[NSNumber numberWithBool:NO] response:nil];
}];
[op4 start];
}
}
I am at a complete loss here because everything was totally fine previously and nothing was touched on my end. What would cause this to completely stop working? I've already tried new client_id and client_secret codes and they produce the same error. Any type of insight would be great.
Looking at the error page that you included in your logs, I see
The page that you requested is invalid. That's all we know.
My app is a webserver app, but I often see the same error page thrown up during authorisation. In my case, I simply Back and retry.
My working assumption is that it's a transient exception thrown somewhere in Google's infrastructure, which materialises in a misleading/meaningless error message.
So for your app, all I can suggest is that you somehow capture that situation and retry the login.

How to enumerate through NSArray of NSDictionaries with a block call inside the loop?

I get an self.usersArray with 2 elements in the format:
(
{
userCreated = "2012-01-05 12:27:22";
username = Simulator;
},
{
userCreated = "2013-01-01 14:27:22";
username = "joey ";
}
)
This is gotten in a completion block after which I call another method to fetch points for these 2 users through a helper class:
-(void)getPoints{
self.usersPointsArray = [[NSMutableArray alloc] init];
for (NSDictionary *usersDictionary in self.usersArray) {
[SantiappsHelper fetchPointsForUser:[usersDictionary objectForKey:#"username"] WithCompletionHandler:^(NSArray *points){
if ([points count] > 0) {
[self.usersPointsArray addObject:[points objectAtIndex:0]];
}
NSLog(#"self.usersPointsArray %#", self.usersPointsArray);
}];
}
}
The final self.usersPointsArray log looks like:
(
{
PUNTOS = 5;
username = Simulator;
},
{
PUNTOS = 2;
username = joey;
}
)
But the problem is that the way the call for points is structured, the self.usersPointsArray is returned twice, each time with an additional object, due to the for loop, I know.
Here is the Helper class method:
+(void)fetchPointsForUser:(NSString*)usuario WithCompletionHandler:(Handler2)handler{
NSURL *url = [NSURL URLWithString:#"http://myserver.com/myapp/readpoints.php"];
NSDictionary *postDict = [NSDictionary dictionaryWithObjectsAndKeys:usuario, #"userNa", nil];
NSData *postData = [self encodeDictionary:postDict];
// Create the request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:[NSString stringWithFormat:#"%d", postData.length] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
__block NSArray *pointsArray = [[NSArray alloc] init];
dispatch_async(dispatch_get_main_queue(), ^{
// Peform the request
NSURLResponse *response;
NSError *error = nil;
NSData *receivedData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error) {
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
NSLog(#"HTTP Error: %d %#", httpResponse.statusCode, error);
return;
}
return;
}
NSString *responseString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
pointsArray = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSASCIIStringEncoding] options:0 error:nil];
if (handler)
handler(pointsArray);
});
}
I cannot use the self.usersPointsArray with the initial objects, only with the finalized object. It wont always be 2 elements, i actually dont know how many it will be.
What would be the way to structure it so I get a final call when the self.usersPointsArray is complete and then I reload my tableview?
I think of your problem as a standard consumer-producer problem. You can create a queue count for the amount of items that will be processed (int totalToProcess=self.usersArray.count). Each time the completion handler is hit, it will do totalToProcess--. When totalToProcess reaches 0 you have processed all of the elements in your queue and can refresh your table.
If I understand your question correctly I believe this solves your problem. If not, hopefully I can with a bit more information.

Getting JSON data from a database via an API, display more results

I am making an application for iOS. The application has to display results from an MYSQL database and I have an API between the app and the database. The database send valid JSON (this is in my browser):
[{"naam":"Maurice","id":2},{"naam":"Klaas","id":6},{"naam":"Mariska","id":8}]
But I cannot see more than one result in my application. I search for example "M" and it only resturns the first Maurice. I want the app to display also Mariska.
Can anyone explain my how to display more than one result, in this case, in my iOS application?
Thanks in advance,
Maurice.
Here more code:
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:#"1" forKey:#"rw_app_id"];
[request setPostValue:voornaam forKey:#"voornaam"];
[request setPostValue:deviceUniqueIdentifier forKey:#"device_id"];
[request setPostValue:#"1" forKey:#"test"];
[request setDelegate:self];
[request startAsynchronous];
// Hide keyword
[textField resignFirstResponder];
// Clear text field
textView.text = #"";
// Start hud
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = #"Zoeken...";
return TRUE;
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
[MBProgressHUD hideHUDForView:self.view animated:YES];
if (request.responseStatusCode == 400) {
textView.text = #"Invalid code";
}
else if (request.responseStatusCode == 403) {
textView.text = #"Code already used";
}
else if (request.responseStatusCode == 204) {
textView.text = #"No content";
}
else if (request.responseStatusCode == 412) {
textView.text = #"Precondition Failed";
}
else if (request.responseStatusCode == 200) {
NSString *responseString = [request responseString];
NSDictionary *responseDict = [responseString JSONValue];
NSString *naam = [responseDict objectForKey:#"naam"];
// if ([unlockCode compare:#"com.razeware.test.unlock.cake"] == NSOrderedSame) {
textView.text = [NSString stringWithFormat:#"Resultaten: %#", naam];
// } else {
// textView.text = [NSString stringWithFormat:#"Resultaat: %#", unlockCode];
// }
}
else {
textView.text = #"Unexpected error API ERROR";
}
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
[MBProgressHUD hideHUDForView:self.view animated:YES];
NSError *error = [request error];
textView.text = error.localizedDescription;
}
#end
`
try this
- (void)requestFinished:(ASIHTTPRequest *)request
{
[MBProgressHUD hideHUDForView:self.view animated:YES];
NSString *strResponse = [request responseString];
SBJSON *objJSONParser = [[SBJSON alloc] init];
NSDictionary *dictData = [objJSONParser objectWithString:strResponse error:nil];
NSDictionary *dictResult = [dictData objectForKey: #"response"];
NSLog(#"result Dict=%#",dictResult)
NSArray *arrTemp=(NSArray *)[dictData objectForKey:#"response"];
NSLog(#"Array=%#",arrTemp)
//print both one by one is it work or not?

Restful API call using IOS with authentication

I am working on an application that uses restful API call using prestashop API. I am new at IOS I coded the same method in android as:
InputStream is = null;
try {
DefaultHttpClient client = new DefaultHttpClient();
/* adding credentials as it is RESTful call */
String username = "xyz";
String password = "";
client.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),new UsernamePasswordCredentials(username, password));
// HTTP get request
HttpGet get = new HttpGet("http://www.example.com/api/");
HttpResponse responseGet;
responseGet = client.execute(get);
is = responseGet.getEntity().getContent();
} catch (ClientProtocolException e) {
Log.e("HTTP Request","Client Protocol exception" );
} catch (IOException e) {
Log.e("HTTP Request","IO exception" );
}
It is working perfectly for Android. For IOS I used this coding but I am not getting data from the server.
NSString *userName = #"XYZ";
NSString *password = #"";
//setting the string of the url taking from appliance IP.
NSString *urlString = #"http://www.example.com/api/";
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"GET"];
NSString *str1 = [NSString stringWithFormat:#"%#:%#",userName,password];
NSLog(#" str1 %#", str1);
[request addValue:[NSString stringWithFormat:#"Basic %#",str1] forHTTPHeaderField:#"Authorization"];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *str = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(#"str: %#", str);
please tell me what I am doing wrong and provide any solution.
Thanks!
You can build the URL string this way and it should work :-
NSString *str1 = [NSString stringWithFormat:#"http://%#:%##www.example.com/api",userName,password];
No need to use the HTTP header fields I believe
Username and password need to be encoded using Base64 encoding when using Basic HTTP authentication.
From Wikipedia's Article on that subject:
Client side
When the user agent wants to send the server authentication
credentials it may use the Authorization header.
The Authorization header is constructed as follows:[6] Username and
password are combined into a string "username:password"
The resulting string literal is then encoded using Base64
The authorization method and a space i.e. "Basic " is then put before
the encoded string. For example, if the user agent uses 'Aladin' as
the username and 'sesam open' as the password then the header is
formed as follows:
Authorization: Basic QWxhZGluOnNlc2FtIG9wZW4=
See this corrected code:
[...]
NSString *str1 = [NSString stringWithFormat:#"%#:%#",userName,password];
NSString *encodedString = [self stringByBase64EncodingWithString:str1];
[request addValue:[NSString stringWithFormat:#"Basic %#",encodedString] forHTTPHeaderField:#"Authorization"];
[...]
- (NSString *)stringByBase64EncodingWithString:(NSString *)inString
{
NSData *data = [NSData dataWithBytes:[inString UTF8String]
length:[inString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
NSUInteger length = [data length];
NSMutableData *mutableData = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t *input = (uint8_t *)[data bytes];
uint8_t *output = (uint8_t *)[mutableData mutableBytes];
for (NSUInteger i = 0; i < length; i += 3)
{
NSUInteger value = 0;
for (NSUInteger j = i; j < (i + 3); j++)
{
value <<= 8;
if (j < length)
{
value |= (0xFF & input[j]);
}
}
static uint8_t const base64EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
NSUInteger idx = (i / 3) * 4;
output[idx + 0] = base64EncodingTable[(value >> 18) & 0x3F];
output[idx + 1] = base64EncodingTable[(value >> 12) & 0x3F];
output[idx + 2] = (i + 1) < length ? base64EncodingTable[(value >> 6) & 0x3F] : '=';
output[idx + 3] = (i + 2) < length ? base64EncodingTable[(value >> 0) & 0x3F] : '=';
}
return [[NSString alloc] initWithData:mutableData encoding:NSASCIIStringEncoding];
}
-(void)getApiCall:(NSString *)urlString response:(NSMutableArray *)response{
NSString *url= urlString;
NSURL * serviceUrl = [NSURL URLWithString:url];
NSMutableURLRequest * serviceRequest = [NSMutableURLRequest requestWithURL:serviceUrl cachePolicy:nil timeoutInterval:10.0];
[serviceRequest setValue:#"Application/json" forHTTPHeaderField:#"Content-type"];
[serviceRequest setHTTPMethod:#"GET"];
NSURLResponse *serviceResponse;
NSError *serviceError;
NSData *responseData = [NSURLConnection sendSynchronousRequest:serviceRequest returningResponse:&serviceResponse error:&serviceError];
NSLog(#"REQUEST ==== >>>> %#",serviceUrl);
NSLog(#"RESPONSE ==== >>>> %#",responseData);
if (responseData != nil){
[self parseGetData:responseData responseArray:response];
}
else{
}
}
-(void)parseGetData:(NSData *)response responseArray:(NSMutableArray *)responseArray
{
id jsonObject = Nil;
NSString *charlieSendString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSLog(#"ResponseString ==== >>>> %#",charlieSendString);
if (response==nil) {
NSLog(#"ERROR IN GET API....!!!!");
}else{
NSError *error = nil;
jsonObject =[NSJSONSerialization JSONObjectWithData:response options:kNilOptions error:&error];
if (error)
{
NSLog(#"%#",error);
}
else
{
NSError *error = Nil;
jsonObject =[NSJSONSerialization JSONObjectWithData:response options:kNilOptions error:&error];
if ([jsonObject isKindOfClass:[NSArray class]]) {
NSLog(#"Probably An Array");
}
else
{
NSLog(#"Probably A Dictionary");
NSDictionary *jsonDictionary=(NSDictionary *)jsonObject;
NSLog(#"jsonDictionary %#",[jsonDictionary description]);
if (jsonDictionary) {
[responseArray addObject:jsonDictionary];
}
}
}
}
}

Resources