AFNetworking 3.0 - wrong authorization code - ios

I'm using AFHTTPSessionManager to GET request with authorization headers;
In case of wrong user/password server according to postman is returning content type : text/html with:
<!DOCTYPE html>
<html>
<head>
<title>Apache Tomcat/8.0.21 - Error report</title>
<style type="text/css">H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}.line {height: 1px; background-color: #525D76; border: none;}</style>
</head>
<body>
<h1>HTTP Status 401 - Błąd podczas autentykacji</h1>
<div class="line"></div>
<p>
<b>type</b> Status report
</p>
<p>
<b>message</b>
<u>Błąd podczas autentykacji</u>
</p>
<p>
<b>description</b>
<u>This request requires HTTP authentication.</u>
</p>
<hr class="line">
<h3>Apache Tomcat/8.0.21</h3>
</body>
</html>
Unfortunately NSURLSessionDataTask returns
NSHTTPURLResponse *test = (NSHTTPURLResponse *)task.response;
NSLog (#"Status code, %i", test.statusCode);
returns Status code, 500
as well as NSError
NSString* errorResponse = [[NSString alloc] initWithData:(NSData *)error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] encoding:NSUTF8StringEncoding];
NSLog(#"Error response: %#", errorResponse);
returns Error response: {"error":{"code":"UNKNOWN_ERROR","details":null,"description":"Server error","version":0}}
This is my get operation method.
- (void)getOperationForAction:(NSString *)action
parameters:(NSArray *)params
completion:(id (^)(id json, BOOL success))completion {
NSURL *url = [self apiUrlForAction:action params:params.mutableCopy];
AFHTTPSessionManager *manager = [self sessionManager];
[manager GET: url.absoluteString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(#"JSON: %#", responseObject);
if (completion) {
completion(responseObject, YES);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSString *responseString = [[NSString alloc] initWithData:(NSData *)error.userInfo[NSLocalizedRecoverySuggestionErrorKey] encoding:NSUTF8StringEncoding];
if(responseString != nil && ![responseString isEqualToString: #""]) {
NSData *JSONData = [responseString dataUsingEncoding: NSUTF8StringEncoding];
id responseJSON = [NSJSONSerialization JSONObjectWithData:JSONData options: NSJSONReadingMutableContainers error:nil];
if(responseJSON != nil) {
}
}
NSHTTPURLResponse *test = (NSHTTPURLResponse *)task.response;
NSLog (#"Status code, %i", test.statusCode);
NSString* errorResponse = [[NSString alloc] initWithData:(NSData *)error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] encoding:NSUTF8StringEncoding];
NSLog(#"Error response: %#", errorResponse);
ApiError *apiError = [[ApiError alloc] initWithString:errorResponse error:nil];
completion(apiError, NO);
}];
}
Request is handled correctly - the 401 issues appeared when I was intentionally using wrong auth login/password just to check the response errors. The problem is with incorrect status code as mentioned before.
#Edit
for
NSHTTPURLResponse *test = (NSHTTPURLResponse *)task.response;
NSLog (#"Status code, %i", test.statusCode);
NSLog (#"Error code, %i", error.code);
NSLog (#"Error domain, %#", error.domain);
Status code, 500
Error code, -1011
Error domain, com.alamofire.error.serialization.response

Related

How to implement refresh token in ios

only some api call needs the token. and when 401 occurs refresh token call will be taken place.and for each call the token is refreshing. how to execute more than 1 api synchronously when 401 occurs
This is upto you, how you design the flow but I did almost same problem like following in Objective C
Call method of like in my case userProfileGETRequest
Before calling userProfileGETRequest Check date if token gets expired(in your case may be status code == 401)
If Token not expired simply call API in my case userProfileAPI with last token
If Token Expired then Call Refresh token and with Success and Failure Callback
If successful refresh token, call the userProfileAPI API with updated refresh token.
+ (void) userProfileGETRequest:(NSDictionary *)headerParams urlQuery: (NSString*)action parameters:(NSDictionary*)params docOpenPassword: (NSString*)password docOpenOtp: (NSString*)otp
onComplete:(void (^)(id json, id code, id url))successBlock
onError:(void (^)(id error, id code, id url))errorBlock {if ([[SingletonSDK sharedInstance] isTokenExpired:[NSDate date]]) {[self refereshToken:nil :^(id json, id code) {
[[SingletonSDK sharedInstance] handleLoginResponseObject:json];
[self userProfileAPI:headerParams urlQuery:action parameters:params
onComplete:^(id json, id code, id url) {
successBlock(json, code, url);
} onError:^(id error, id code, id url) {
errorBlock(error, code, url);
}];
} onError:^(id error, id code) {
[[SingletonSDK sharedInstance] hideProgessHud];
return ;
}];
}
} else {
[self userProfileAPI:headerParams urlQuery:action parameters:params
onComplete:^(id json, id code, id url) {
successBlock(json, code, url);
} onError:^(id error, id code, id url) {
errorBlock(error, code, url);
}];
}}
//userProfileAPI Methods
+ (void) userProfileAPI:(NSDictionary *)headerParams urlQuery: (NSString*)action parameters:(NSDictionary*)params
onComplete:(void (^)(id json, id code, id url))successBlock
onError:(void (^)(id error, id code, id url))errorBlock
{
NSString *authorizationValue = [self setAuthorizationValue:action];
NSString *language = [self editedLanguageNameAsApiRequired];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
//set headers values
[manager.requestSerializer setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[manager.requestSerializer setValue:language forHTTPHeaderField:#"Accept-Language"];
[manager.requestSerializer setValue:authorizationValue forHTTPHeaderField:#"authorization"];
[manager GET:action parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"getRequest response success");
NSString *url = [[[operation response] URL] absoluteString];
NSInteger statusCode = [operation.response statusCode];
NSNumber *statusObject = [NSNumber numberWithInteger:statusCode];
successBlock(responseObject, statusObject, url);
}
failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSString *url = [[[operation response] URL] absoluteString];
NSInteger statusCode = [operation.response statusCode];
NSNumber *statusObject = [NSNumber numberWithInteger:statusCode];
if ([self takeDesiredActionIfAccessTokenExpired:statusCode]) {
return ;
}
id responseObject = operation.responseData;
id json = nil;
id errorMessage = nil;
if ([statusObject integerValue] == 404) {
errorMessage = [[SingletonSDK sharedInstance] getStringValueFromLanguageKey: COMMON_ERROR_SHARED_PREFERENCES];//NSLocalizedString(COMMON_ERROR_RESOURCE_NOT_FOUND, nil);
} else {
if (responseObject) {
json = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
errorMessage = [(NSDictionary*)json objectForKey:#"Message"];
}else{
json = [error.userInfo objectForKey:NSLocalizedDescriptionKey];
errorMessage = json;
}
}
if(![errorMessage isKindOfClass:[NSString class]]){
errorMessage = [[SingletonSDK sharedInstance] getStringValueFromLanguageKey: COMMON_ERROR_MSG] ; //NSLocalizedString(COMMON_ERROR_MSG, nil);
}
}];
}

NSURLConnection wrong order

I have a NSURLConnection (two of them), and they're running in the wrong order.
Here's my method:
- (void)loginToMistarWithPin:(NSString *)pin password:(NSString *)password {
NSURL *url = [NSURL URLWithString:#"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/Login"];
//Create and send request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"POST"];
NSString *postString = [NSString stringWithFormat:#"Pin=%#&Password=%#",
[self percentEscapeString:pin],
[self percentEscapeString:password]];
NSData * postBody = [postString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:postBody];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
// do whatever with the data...and errors
if ([data length] > 0 && error == nil) {
NSError *parseError;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (responseJSON) {
// the response was JSON and we successfully decoded it
NSLog(#"Response was = %#", responseJSON);
} else {
// the response was not JSON, so let's see what it was so we can diagnose the issue
NSString *loggedInPage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response was not JSON (from login), it was = %#", loggedInPage);
}
}
else {
NSLog(#"error: %#", error);
}
}];
//Now redirect to assignments page
NSURL *homeURL = [NSURL URLWithString:#"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/PortalMainPage"];
NSMutableURLRequest *requestHome = [[NSMutableURLRequest alloc] initWithURL:homeURL];
[request setHTTPMethod:#"POST"];
[NSURLConnection sendAsynchronousRequest:requestHome queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *homeResponse, NSData *homeData, NSError *homeError)
{
// do whatever with the data...and errors
if ([homeData length] > 0 && homeError == nil) {
NSError *parseError;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:homeData options:0 error:&parseError];
if (responseJSON) {
// the response was JSON and we successfully decoded it
NSLog(#"Response was = %#", responseJSON);
} else {
// the response was not JSON, so let's see what it was so we can diagnose the issue
NSString *homePage = [[NSString alloc] initWithData:homeData encoding:NSUTF8StringEncoding];
NSLog(#"Response was not JSON (from home), it was = %#", homePage);
}
}
else {
NSLog(#"error: %#", homeError);
}
}];
}
- (NSString *)percentEscapeString:(NSString *)string
{
NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)string,
(CFStringRef)#" ",
(CFStringRef)#":/?#!$&'()*+,;=",
kCFStringEncodingUTF8));
return [result stringByReplacingOccurrencesOfString:#" " withString:#"+"];
}
So, it's two NSURLConnection's that are added to the [NSOperationQueue mainQueue]. What my output is showing me is that the second NSURLConnection is running before the first one. So it tries to go to the page where I download data before I'm logged in, so it (obviously) returns a "You're not logged in" error.
How do I schedule them one after another?
The issue, as I suspect you have realized, is that you're doing asynchronous network requests (which is good; you don't want to block the main queue), so there's no assurance of the order they'll finish.
The quickest and easiest answer is to simply put the call to the second request inside the completion block of the first one, not after it. You don't want to be making that second one unless the first one succeeded anyway.
To keep your code from getting unwieldy, separate the login from the request for main page. And you can use the completion block pattern which is common with asynchronous methods. You add a parameter to loginToMistarWithPin that specifies what it should do when the request finishes. You might have one completion block handler for success, and one for failure:
- (void)loginToMistarWithPin:(NSString *)pin password:(NSString *)password success:(void (^)(void))successHandler failure:(void (^)(void))failureHandler {
NSURL *url = [NSURL URLWithString:#"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/Login"];
//Create and send request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"POST"];
NSString *postString = [NSString stringWithFormat:#"Pin=%#&Password=%#",
[self percentEscapeString:pin],
[self percentEscapeString:password]];
NSData * postBody = [postString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:postBody];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
// do whatever with the data...and errors
if ([data length] > 0 && error == nil) {
NSError *parseError;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (responseJSON) {
// the response was JSON and we successfully decoded it
NSLog(#"Response was = %#", responseJSON);
// assuming you validated that everything was successful, call the success block
if (successHandler)
successHandler();
} else {
// the response was not JSON, so let's see what it was so we can diagnose the issue
NSString *loggedInPage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response was not JSON (from login), it was = %#", loggedInPage);
if (failureHandler)
failureHandler();
}
}
else {
NSLog(#"error: %#", error);
if (failureHandler)
failureHandler();
}
}];
}
- (void)requestMainPage {
//Now redirect to assignments page
NSURL *homeURL = [NSURL URLWithString:#"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/PortalMainPage"];
NSMutableURLRequest *requestHome = [[NSMutableURLRequest alloc] initWithURL:homeURL];
[requestHome setHTTPMethod:#"GET"]; // this looks like GET request, not POST
[NSURLConnection sendAsynchronousRequest:requestHome queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *homeResponse, NSData *homeData, NSError *homeError)
{
// do whatever with the data...and errors
if ([homeData length] > 0 && homeError == nil) {
NSError *parseError;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:homeData options:0 error:&parseError];
if (responseJSON) {
// the response was JSON and we successfully decoded it
NSLog(#"Response was = %#", responseJSON);
} else {
// the response was not JSON, so let's see what it was so we can diagnose the issue
NSString *homePage = [[NSString alloc] initWithData:homeData encoding:NSUTF8StringEncoding];
NSLog(#"Response was not JSON (from home), it was = %#", homePage);
}
}
else {
NSLog(#"error: %#", homeError);
}
}];
}
Then, when you want to login, you can do something like:
[self loginToMistarWithPin:#"1234" password:#"pass" success:^{
[self requestMainPage];
} failure:^{
NSLog(#"login failed");
}];
Now, change those successHandler and failureHandler block parameters to include whatever data you need to pass back, but hopefully it illustrates the idea. Keep your methods short and tight, and use completion block parameters to specify what an asynchronous method should do when it's done.
Can you check the below link. It is about forcing one operation to wait for another.
NSOperation - Forcing an operation to wait others dynamically
Hope this helps.

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.

AFNetworking Expected status code in (200-299), got 403

Trying to migrate my code from ASIHttpRequest to AFNetworking. It seems similar questions has been asked but couldnt find solution to my problem.
My code was working fine with ASIHttpRquest.
I send a simple post request to my server and listen http responses. If http response is 200 everything works fine but if I send another status code >400 AFNetworking block fails.
Server side response:
$rc = $stmt->fetch();
if ( !$rc ) {
// echo "no such record\n";
$isrecordExist=0; //false does not exists
sendResponse(403, 'Login Failed');
return false;
}
else {
// echo 'result: ', $result, "\n";
$sendarray = array(
"user_id" => $result,
);
sendResponse(200, json_encode($sendarray));
}
IOS Part:
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:
[NSURL URLWithString:server]];
client.allowsInvalidSSLCertificate=YES;
[client postPath:loginForSavingCredientials parameters:params success:^(AFHTTPRequestOperation *operation, id response) {
if (operation.response.statusCode == 500) {}
else if (operation.response.statusCode == 403) {}
else if (operation.response.statusCode == 200) {//able to get results here NSError* error;
NSString *responseString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSDictionary* json = [NSJSONSerialization JSONObjectWithData: [responseString dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &error];}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failure %#", [error localizedDescription]);
}];
NSLOG:
failure Expected status code in (200-299), got 403
How can I fix this?
When AFNetworking gets a 2xx (success) status code, it calls the success block.
When it gets a 4xx (client error) or 5xx (server error) status code, it calls the failure block because something went wrong.
So all you should need to do is move your check for a 500 or 403 status code to the failure block.
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:server]];
client.allowsInvalidSSLCertificate=YES;
[client postPath:loginForSavingCredientials parameters:params success:^(AFHTTPRequestOperation *operation, id response) {
if (operation.response.statusCode == 200) {//able to get results here NSError* error;
NSString *responseString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSDictionary* json = [NSJSONSerialization JSONObjectWithData: [responseString dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &error];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"failure %#", [error localizedDescription]);
if (operation.response.statusCode == 500) {}
else if (operation.response.statusCode == 403) {}
}];
When you create the request operation you need to tell it which response status codes are acceptable (mean success). By default this is codes in the range 200 -> 299.
Setup before you start using the client:
AFHTTPRequestOperation.acceptableStatusCodes = ...;
[client postPath:
Docs are here.

AFNetworking retry timeout requests using enqueueBatchOfHTTPRequestOperations

There are few similar questions to mine with answers,but could not find a way to use that solutions on my code. I would be glad, if anyone can help me on code. How to retry timeout request?
while block for pagination purpose:
while(mult < (int)totalCount) {
AFHTTPRequestOperation *opr = [self getRequestForAllRecordsOfClass:className updatedAfterDate:mostRecentUpdatedDate withinPage:page+1];
[pagedOperations addObject:opr];
mult = mult + PAGINATION_SIZE;
page = page + 1;
}
[[SDAFParseAPIClient sharedClient] enqueueBatchOfHTTPRequestOperations:operations progressBlock:^(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations) {
NSLog(#"totalNumberOfOperations: %u numberOfCompletedOperations: %u",totalNumberOfOperations,numberOfCompletedOperations);
} completionBlock:^(NSArray *operations) {
...
}];
and building request operation
-(AFHTTPRequestOperation *)getRequestForAllRecordsOfClass:(NSString *)className updatedAfterDate:(NSDate *)mostRecentDate withinPage:(int)page {
NSMutableURLRequest *request = [ZurmoHelper GETRequestForAllRecordsOfClass:className updatedAfterDate:mostRecentDate inPage:page];
AFHTTPRequestOperation *operation = [[SDAFParseAPIClient sharedClient] HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"RESPONSE pagination!!! %#:", className);
NSError *error = nil; //error in parsing json
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
if (!error) {
NSLog(#"json dict paged in : %d",page );
id dataObject = [jsonDict objectForKey:#"data"];
NSArray *itemsObject = [dataObject objectForKey:#"items"];
[self addItems:itemsObject className:className];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Request for class %# failed with error: %#", className, error);
if (error.code == -1001) {
NSLog(#"for class %# page: %d,",className,page);
//need to retry this operation???
}
}];
return operation;
}

Resources