Skip to content

Commit

Permalink
Merged sessionDelegates in the Hackbook sample.
Browse files Browse the repository at this point in the history
Summary: Current Hackbook example implements two FBSessionDelegates. Switching
between them requires modifying the internals of Facebook class and is very
confusing. The solution is to remove FBSessionDelegate implementation from
APICallsViewController, and modify the code in a way that will work with only
one sessionDelegate.

Test Plan:
Try the following (two times every plan :) ):
  - login, execute any method, logout
  - login, execute any method, uninstall app
  - login, cancel login, login, execute any method, logout
  - login, request additional perms, cancel, request additional perms, grant,
logout

Reviewers: yariv

Reviewed By: yariv

CC: jimbru, lshepard, kamil, yariv

Differential Revision: 377641
  • Loading branch information
Kamil Kraszewski authored and Kamil Kraszewski committed Dec 14, 2011
1 parent 318fa29 commit e79d072
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 106 deletions.
5 changes: 4 additions & 1 deletion sample/Hackbook/Hackbook/APICallsViewController.h
Expand Up @@ -47,7 +47,6 @@ typedef enum apiCall {
@interface APICallsViewController : UIViewController
<FBRequestDelegate,
FBDialogDelegate,
FBSessionDelegate,
UITableViewDataSource,
UITableViewDelegate,
CLLocationManagerDelegate>{
Expand Down Expand Up @@ -76,4 +75,8 @@ CLLocationManagerDelegate>{

- (id)initWithIndex:(NSUInteger)index;

- (void)userDidGrantPermission;

- (void)userDidNotGrantPermission;

@end
55 changes: 8 additions & 47 deletions sample/Hackbook/Hackbook/APICallsViewController.m
Expand Up @@ -145,27 +145,6 @@ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface
}

#pragma mark - Private Helper Methods
/*
* This method is called after the user logs out or unauthorized the application
* and returns the flow back to the main menu.
*/
- (void)backToMain {
// Remove saved authorization information
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:@"FBAccessTokenKey"];
[defaults removeObjectForKey:@"FBExpirationDateKey"];
[defaults synchronize];

// Pop to main view
HackbookAppDelegate *delegate = (HackbookAppDelegate *)[[UIApplication sharedApplication] delegate];
RootViewController *rootViewController = (RootViewController *)[[self.navigationController viewControllers] objectAtIndex:0];
// Set the delegate to the main root view controller
// to ensure if an SSO request comes in this controller
// will handle it.
[delegate facebook].sessionDelegate = rootViewController;
[[delegate navigationController] popToRootViewControllerAnimated:YES];
}

/*
* This method is called to store the check-in permissions
* in the app session after the permissions have been updated.
Expand Down Expand Up @@ -319,7 +298,6 @@ - (void)apiGraphUserPermissions {
- (void)apiPromptCheckinPermissions {
HackbookAppDelegate *delegate = (HackbookAppDelegate *)[[UIApplication sharedApplication] delegate];
NSArray *checkinPermissions = [[NSArray alloc] initWithObjects:@"user_checkins", @"publish_checkins", nil];
[delegate facebook].sessionDelegate = self;
[[delegate facebook] authorize:checkinPermissions];
[checkinPermissions release];
}
Expand All @@ -336,7 +314,7 @@ - (void)apiPromptCheckinPermissions {
- (void)apiLogout {
currentAPICall = kAPILogout;
HackbookAppDelegate *delegate = (HackbookAppDelegate *)[[UIApplication sharedApplication] delegate];
[[delegate facebook] logout:self];
[[delegate facebook] logout];
}

/*
Expand All @@ -362,7 +340,6 @@ - (void)apiPromptExtendedPermissions {
currentAPICall = kDialogPermissionsExtended;
HackbookAppDelegate *delegate = (HackbookAppDelegate *)[[UIApplication sharedApplication] delegate];
NSArray *extendedPermissions = [[NSArray alloc] initWithObjects:@"user_likes", nil];
[delegate facebook].sessionDelegate = self;
[[delegate facebook] authorize:extendedPermissions];
[extendedPermissions release];
}
Expand Down Expand Up @@ -954,7 +931,10 @@ - (void)request:(FBRequest *)request didLoad:(id)result {
// the app from thinking there is a valid session
[delegate facebook].accessToken = nil;
[delegate facebook].expirationDate = nil;
[self backToMain];

// Notify the root view about the logout.
RootViewController *rootViewController = (RootViewController *)[[self.navigationController viewControllers] objectAtIndex:0];
[rootViewController fbDidLogout];
break;
}
case kAPIFriendsForDialogFeed:
Expand Down Expand Up @@ -1208,19 +1188,10 @@ - (void)dialog:(FBDialog*)dialog didFailWithError:(NSError *)error {
[self showMessage:@"Oops, something went haywire."];
}

#pragma mark - FBSessionDelegate Methods
/**
* Called when the user has logged in successfully.
* Called when the user granted additional permissions.
*/
- (void)fbDidLogin {
HackbookAppDelegate *delegate = (HackbookAppDelegate *)[[UIApplication sharedApplication] delegate];

// Save updated authorization information
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[[delegate facebook] accessToken] forKey:@"FBAccessTokenKey"];
[defaults setObject:[[delegate facebook] expirationDate] forKey:@"FBExpirationDateKey"];
[defaults synchronize];

- (void)userDidGrantPermission {
// After permissions granted follow up with next API call
switch (currentAPICall) {
case kDialogPermissionsCheckinForRecent:
Expand Down Expand Up @@ -1256,18 +1227,8 @@ - (void)fbDidLogin {
/**
* Called when the user canceled the authorization dialog.
*/
- (void)fbDidNotLogin:(BOOL)cancelled {
NSLog(@"did not login");
- (void)userDidNotGrantPermission {
[self showMessage:@"Extended permissions not granted."];
}

/**
* Called when the request logout has succeeded.
*/
- (void)fbDidLogout {
// Go back to main menu
[self backToMain];
}


@end
3 changes: 3 additions & 0 deletions sample/Hackbook/Hackbook/RootViewController.h
Expand Up @@ -15,6 +15,7 @@
*/

#import <UIKit/UIKit.h>
#import "APICallsViewController.h"
#import "FBConnect.h"

@interface RootViewController : UIViewController
Expand All @@ -34,6 +35,8 @@ UITableViewDelegate>{
UIView *headerView;
UILabel *nameLabel;
UIImageView *profilePhotoImageView;

APICallsViewController *pendingApiCallsController;
}

@property (nonatomic, retain) NSArray *permissions;
Expand Down
53 changes: 21 additions & 32 deletions sample/Hackbook/Hackbook/RootViewController.m
Expand Up @@ -92,26 +92,8 @@ - (void)showLoggedIn {
* Show the logged in menu
*/

- (void)showLoggedOut:(BOOL)clearInfo {
- (void)showLoggedOut {
[self.navigationController setNavigationBarHidden:YES animated:NO];
// Remove saved authorization information if it exists and it is
// ok to clear it (logout, session invalid, app unauthorized)
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (clearInfo && [defaults objectForKey:@"FBAccessTokenKey"]) {
[defaults removeObjectForKey:@"FBAccessTokenKey"];
[defaults removeObjectForKey:@"FBExpirationDateKey"];
[defaults synchronize];

// Nil out the session variables to prevent
// the app from thinking there is a valid session
HackbookAppDelegate *delegate = (HackbookAppDelegate *)[[UIApplication sharedApplication] delegate];
if (nil != [[delegate facebook] accessToken]) {
[delegate facebook].accessToken = nil;
}
if (nil != [[delegate facebook] expirationDate]) {
[delegate facebook].expirationDate = nil;
}
}

self.menuTableView.hidden = YES;
self.backgroundImageView.hidden = NO;
Expand All @@ -121,22 +103,16 @@ - (void)showLoggedOut:(BOOL)clearInfo {
nameLabel.text = @"";
// Get the profile image
[profilePhotoImageView setImage:nil];

[[self navigationController] popToRootViewControllerAnimated:YES];
}

/**
* Show the authorization dialog.
*/
- (void)login {
HackbookAppDelegate *delegate = (HackbookAppDelegate *)[[UIApplication sharedApplication] delegate];
// Check and retrieve authorization information
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:@"FBAccessTokenKey"]
&& [defaults objectForKey:@"FBExpirationDateKey"]) {
[delegate facebook].accessToken = [defaults objectForKey:@"FBAccessTokenKey"];
[delegate facebook].expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];
}
if (![[delegate facebook] isSessionValid]) {
[delegate facebook].sessionDelegate = self;
[[delegate facebook] authorize:permissions];
} else {
[self showLoggedIn];
Expand All @@ -148,7 +124,7 @@ - (void)login {
*/
- (void)logout {
HackbookAppDelegate *delegate = (HackbookAppDelegate *)[[UIApplication sharedApplication] delegate];
[[delegate facebook] logout:self];
[[delegate facebook] logout];
}

/**
Expand All @@ -162,6 +138,7 @@ - (void)menuButtonClicked:(id)sender {
// which menu button was clicked.
APICallsViewController *controller = [[APICallsViewController alloc]
initWithIndex:[sender tag]];
pendingApiCallsController = controller;
[self.navigationController pushViewController:controller animated:YES];
[controller release];
}
Expand Down Expand Up @@ -254,6 +231,7 @@ - (void)loadView {

[self.view addSubview:menuTableView];

pendingApiCallsController = nil;
}

- (void)viewDidUnload {
Expand All @@ -275,7 +253,7 @@ - (void)viewWillAppear:(BOOL)animated {
[delegate facebook].expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];
}
if (![[delegate facebook] isSessionValid]) {
[self showLoggedOut:NO];
[self showLoggedOut];
} else {
[self showLoggedIn];
}
Expand Down Expand Up @@ -351,20 +329,31 @@ - (void)fbDidLogin {
[defaults setObject:[[delegate facebook] accessToken] forKey:@"FBAccessTokenKey"];
[defaults setObject:[[delegate facebook] expirationDate] forKey:@"FBExpirationDateKey"];
[defaults synchronize];

[pendingApiCallsController userDidGrantPermission];
}

/**
* Called when the user canceled the authorization dialog.
*/
-(void)fbDidNotLogin:(BOOL)cancelled {
NSLog(@"did not login");
[pendingApiCallsController userDidNotGrantPermission];
}

/**
* Called when the request logout has succeeded.
*/
- (void)fbDidLogout {
[self showLoggedOut:YES];
pendingApiCallsController = nil;

// Remove saved authorization information if it exists and it is
// ok to clear it (logout, session invalid, app unauthorized)
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:@"FBAccessTokenKey"];
[defaults removeObjectForKey:@"FBExpirationDateKey"];
[defaults synchronize];

[self showLoggedOut];
}

#pragma mark - FBRequestDelegate Methods
Expand Down Expand Up @@ -447,7 +436,7 @@ - (void)request:(FBRequest *)request didFailWithError:(NSError *)error {
// 2. the user logged out of Facebook from m.facebook.com or the Facebook app
// 3. the user has changed their password
if ([error code] == 190) {
[self showLoggedOut:YES];
[self fbDidLogout];
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Facebook.h
Expand Up @@ -53,7 +53,7 @@

- (BOOL)handleOpenURL:(NSURL *)url;

- (void)logout:(id<FBSessionDelegate>)delegate;
- (void)logout;

- (FBRequest*)requestWithParams:(NSMutableDictionary *)params
andDelegate:(id <FBRequestDelegate>)delegate;
Expand Down
44 changes: 19 additions & 25 deletions src/Facebook.m
Expand Up @@ -365,30 +365,24 @@ - (BOOL)handleOpenURL:(NSURL *)url {
* it just removes the access token. To unauthorize the application,
* the user must remove the app in the app settings page under the privacy
* settings screen on facebook.com.
*
* @param delegate
* Callback interface for notifying the calling application when
* the application has logged out
*/
- (void)logout:(id<FBSessionDelegate>)delegate {

self.sessionDelegate = delegate;
[_accessToken release];
_accessToken = nil;
[_expirationDate release];
_expirationDate = nil;

NSHTTPCookieStorage* cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray* facebookCookies = [cookies cookiesForURL:
[NSURL URLWithString:@"http://login.facebook.com"]];

for (NSHTTPCookie* cookie in facebookCookies) {
[cookies deleteCookie:cookie];
}

if ([self.sessionDelegate respondsToSelector:@selector(fbDidLogout)]) {
[_sessionDelegate fbDidLogout];
}
- (void)logout {
[_accessToken release];
_accessToken = nil;
[_expirationDate release];
_expirationDate = nil;

NSHTTPCookieStorage* cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray* facebookCookies = [cookies cookiesForURL:
[NSURL URLWithString:@"http://login.facebook.com"]];

for (NSHTTPCookie* cookie in facebookCookies) {
[cookies deleteCookie:cookie];
}

if ([self.sessionDelegate respondsToSelector:@selector(fbDidLogout)]) {
[self.sessionDelegate fbDidLogout];
}
}

/**
Expand Down Expand Up @@ -626,7 +620,7 @@ - (void)fbDialogLogin:(NSString *)token expirationDate:(NSDate *)expirationDate
self.accessToken = token;
self.expirationDate = expirationDate;
if ([self.sessionDelegate respondsToSelector:@selector(fbDidLogin)]) {
[_sessionDelegate fbDidLogin];
[self.sessionDelegate fbDidLogin];
}

}
Expand All @@ -636,7 +630,7 @@ - (void)fbDialogLogin:(NSString *)token expirationDate:(NSDate *)expirationDate
*/
- (void)fbDialogNotLogin:(BOOL)cancelled {
if ([self.sessionDelegate respondsToSelector:@selector(fbDidNotLogin:)]) {
[_sessionDelegate fbDidNotLogin:cancelled];
[self.sessionDelegate fbDidNotLogin:cancelled];
}
}

Expand Down

0 comments on commit e79d072

Please sign in to comment.