Permalink
Browse files

Improve FBRequestConnection error handling & iOS 6.0 permission bookk…

…eeping

Summary:
Added a feature to FBRequestConnection to inform iOS 6.0 of permission related
failures. Added code to scrumptious to handle the case where a user explicitly
removes permissions.

Test Plan: Test the new flow via the new features in scrumptious

Reviewers: chrisp, clang

Reviewed By: chrisp

CC: gregschechte

Differential Revision: https://phabricator.fb.com/D589964

Task ID: 1778969
  • Loading branch information...
1 parent b631537 commit 0b3d28b7bea8b63dd9efca67e1438d72fc78daf5 @onebit onebit committed Oct 2, 2012
Showing with 69 additions and 16 deletions.
  1. +27 −11 samples/Scrumptious/scrumptious/SCViewController.m
  2. +42 −5 src/FBRequestConnection.m
@@ -134,26 +134,42 @@ - (void)postOpenGraphAction {
[self.activityIndicator stopAnimating];
[self.view setUserInteractionEnabled:YES];
- NSString *alertText;
if (!error) {
- alertText = [NSString stringWithFormat:@"Posted Open Graph action, id: %@",
- [result objectForKey:@"id"]];
+ [[[UIAlertView alloc] initWithTitle:@"Result"
+ message:[NSString stringWithFormat:@"Posted Open Graph action, id: %@",
+ [result objectForKey:@"id"]]
+ delegate:nil
+ cancelButtonTitle:@"Thanks!"
+ otherButtonTitles:nil]
+ show];
// start over
self.selectedMeal = nil;
self.selectedPlace = nil;
self.selectedFriends = nil;
[self updateSelections];
} else {
- alertText = [NSString stringWithFormat:@"error: domain = %@, code = %d",
- error.domain, error.code];
+ // do we lack permissions here? If so, the application's policy is to reask for the permissions, and if
+ // granted, we will recall this method in order to post the action
+ if ([[error userInfo][FBErrorParsedJSONResponseKey][@"body"][@"error"][@"code"] compare:@200] == NSOrderedSame) {
+ [FBSession.activeSession reauthorizeWithPublishPermissions:[NSArray arrayWithObject:@"publish_actions"]
+ defaultAudience:FBSessionDefaultAudienceFriends
+ completionHandler:^(FBSession *session, NSError *error) {
+ if (!error) {
+ // re-call assuming we now have the permission
+ [self postOpenGraphAction];
+ }
+ }];
+ } else {
+ [[[UIAlertView alloc] initWithTitle:@"Result"
+ message:[NSString stringWithFormat:@"error: domain = %@, code = %d",
+ error.domain, error.code]
+ delegate:nil
+ cancelButtonTitle:@"Thanks!"
+ otherButtonTitles:nil]
+ show];
+ }
}
- [[[UIAlertView alloc] initWithTitle:@"Result"
- message:alertText
- delegate:nil
- cancelButtonTitle:@"Thanks!"
- otherButtonTitles:nil]
- show];
}];
}
View
@@ -53,6 +53,7 @@
NSString *const FBNonJSONResponseProperty = @"FACEBOOK_NON_JSON_RESULT";
static const int kRESTAPIAccessTokenErrorCode = 190;
+static const int kRESTAPIPermissionErrorCode = 200;
static const int kAPISessionNoLongerActiveErrorCode = 2500;
static const NSTimeInterval kDefaultTimeout = 180.0;
static const int kMaximumBatchSize = 50;
@@ -1148,8 +1149,16 @@ - (void)completeWithResults:(NSArray *)results
NSDictionary *resultDictionary = (NSDictionary *)result;
body = [FBGraphObject graphObjectWrappingDictionary:[resultDictionary objectForKey:@"body"]];
}
-
- if ([self isInvalidSessionError:itemError
+
+ // if we lack permissions, use this as a cue to refresh the
+ // OS's understanding of current permissions
+ if ((metadata.request.session.loginType == FBSessionLoginTypeSystemAccount) &&
+ [self isInsufficientPermissionError:error
+ resultIndex:error == itemError ? i : 0]) {
+ [FBSession renewSystemAuthorization];
+ }
+
+ if ([self isInvalidSessionError:itemError
resultIndex:error == itemError ? i : 0]) {
[metadata.request.session closeAndClearTokenInformation:itemError];
if (metadata.request.session.loginType == FBSessionLoginTypeSystemAccount){
@@ -1274,8 +1283,9 @@ - (NSError *)checkConnectionError:(NSError *)innerError
return result;
}
-- (BOOL)isInvalidSessionError:(NSError *)error
- resultIndex:(int)index {
+- (BOOL)getCodeValueForError:(NSError *)error
+ resultIndex:(int)index
+ value:(int *)pvalue {
// does this error have a response? that is an array?
id response = [error.userInfo objectForKey:FBErrorParsedJSONResponseKey];
@@ -1292,13 +1302,40 @@ - (BOOL)isInvalidSessionError:(NSError *)error
(code = [error objectForKey:@"code"]) && // response[index].body.error.code
[code isKindOfClass:[NSNumber class]]) {
// is it a 190 packaged in the original response, then YES
- return [code intValue] == kRESTAPIAccessTokenErrorCode || [code intValue] == kAPISessionNoLongerActiveErrorCode;
+ if (pvalue) {
+ *pvalue = [code intValue];
+ }
+ return YES;
}
}
// else NO
return NO;
}
+- (BOOL)isInsufficientPermissionError:(NSError *)error
+ resultIndex:(int)index {
+
+ int value;
+ if ([self getCodeValueForError:error
+ resultIndex:index
+ value:&value]) {
+ return value == kRESTAPIPermissionErrorCode;
+ }
+ return NO;
+}
+
+- (BOOL)isInvalidSessionError:(NSError *)error
+ resultIndex:(int)index {
+
+ int value;
+ if ([self getCodeValueForError:error
+ resultIndex:index
+ value:&value]) {
+ return value == kRESTAPIAccessTokenErrorCode || value == kAPISessionNoLongerActiveErrorCode;
+ }
+ return NO;
+}
+
- (void)registerTokenToOmitFromLog:(NSString *)token
{
if (![[FBSettings loggingBehavior] containsObject:FBLoggingBehaviorAccessTokens]) {

0 comments on commit 0b3d28b

Please sign in to comment.