From 1e31ba965e82a00aeb136bcf99ac25abac714ae0 Mon Sep 17 00:00:00 2001 From: Yariv Sadan Date: Thu, 10 Feb 2011 11:50:15 -0800 Subject: [PATCH] Add the 'localAppId' param to [Facebook authorize] Summary: This is the SDK diff to support the local_client_id URL parameter that we added to the FB app. I named it 'localAppId' to be consistent with the 'appId' parameter to the same function. Test Plan: bound the demo app to 'fb1234foo' and passed 'foo' as the localAppId value. verified the SDK used the 'fbauth2' url scheme to open the fb app and that the fb app successfully redirected back to the demo app. Reviewed By: brent Reviewers: lshepard, atishm, brent, oyamauchi, jimbru CC: brent Differential Revision: 211201 --- .gitignore | 3 + .../DemoApp/DemoApp.xcodeproj/project.pbxproj | 2 + src/Facebook.h | 8 +- src/Facebook.m | 83 ++++++++++++++++--- 4 files changed, 82 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index e57f8d81ac..a1d0732eea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ sample/DemoApp/build/ sample/DemoApp/DemoApp.xcodeproj/*.pbxuser sample/DemoApp/DemoApp.xcodeproj/*.mode* +sample/DemoApp/DemoApp.xcodeproj/xcuserdata* +sample/DemoApp/DemoApp.xcodeproj/project.xcworkspace sample/theRunAround/build/ sample/theRunAround/theRunAround.xcodeproj/*.pbxuser sample/theRunAround/theRunAround.xcodeproj/*.mode* @@ -12,3 +14,4 @@ test/UnitTest/UnitTest.xcodeproj/*.mode* test/UnitTest/build/ *~ *# +.arcconfig \ No newline at end of file diff --git a/sample/DemoApp/DemoApp.xcodeproj/project.pbxproj b/sample/DemoApp/DemoApp.xcodeproj/project.pbxproj index 0e008c370a..375cc51527 100755 --- a/sample/DemoApp/DemoApp.xcodeproj/project.pbxproj +++ b/sample/DemoApp/DemoApp.xcodeproj/project.pbxproj @@ -289,6 +289,7 @@ "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = 1; + VALID_ARCHS = "armv7 armv6 i386"; }; name = Debug; }; @@ -308,6 +309,7 @@ SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = 1; VALIDATE_PRODUCT = YES; + VALID_ARCHS = "armv7 armv6 i386"; }; name = Release; }; diff --git a/src/Facebook.h b/src/Facebook.h index e469d57337..9c391798b4 100644 --- a/src/Facebook.h +++ b/src/Facebook.h @@ -33,20 +33,24 @@ FBDialog* _loginDialog; FBDialog* _fbDialog; NSString* _appId; + NSString* _localAppId; NSArray* _permissions; } @property(nonatomic, copy) NSString* accessToken; - @property(nonatomic, copy) NSDate* expirationDate; - @property(nonatomic, assign) id sessionDelegate; +@property(nonatomic, copy) NSString* localAppId; - (id)initWithAppId:(NSString *)app_id; - (void)authorize:(NSArray *)permissions delegate:(id)delegate; +- (void)authorize:(NSArray *)permissions + delegate:(id)delegate + localAppId:(NSString *)localAppId; + - (BOOL)handleOpenURL:(NSURL *)url; - (void)logout:(id)delegate; diff --git a/src/Facebook.m b/src/Facebook.m index 2381ea31d8..c22347813e 100644 --- a/src/Facebook.m +++ b/src/Facebook.m @@ -22,7 +22,8 @@ static NSString* kGraphBaseURL = @"https://graph.facebook.com/"; static NSString* kRestserverBaseURL = @"https://api.facebook.com/method/"; -static NSString* kFBAppAuthURL = @"fbauth://authorize"; +static NSString* kFBAppAuthURLScheme = @"fbauth"; +static NSString* kFBAppAuthURLPath = @"authorize"; static NSString* kRedirectURL = @"fbconnect://success"; static NSString* kLogin = @"oauth"; @@ -31,11 +32,26 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// +@interface Facebook () + +// private properties + +@property(nonatomic, copy) NSString* appId; +@property(nonatomic, retain) NSArray* permissions; + +@end + +/////////////////////////////////////////////////////////////////////////////////////////////////// + @implementation Facebook @synthesize accessToken = _accessToken, expirationDate = _expirationDate, - sessionDelegate = _sessionDelegate; + sessionDelegate = _sessionDelegate, + permissions = _permissions, + appId = _appId, + localAppId = _localAppId; + /////////////////////////////////////////////////////////////////////////////////////////////////// // private @@ -64,6 +80,7 @@ - (void)dealloc { [_fbDialog release]; [_appId release]; [_permissions release]; + [_localAppId release]; [super dealloc]; } @@ -101,6 +118,15 @@ - (FBRequest*)openUrl:(NSString *)url return _request; } +/** + * A private function for getting the app's base url. + */ +- (NSString *)getOwnBaseUrl { + return [NSString stringWithFormat:@"fb%@%@://authorize", + _appId, + _localAppId ? _localAppId : @""]; +} + /** * A private function for opening the authorization dialog. */ @@ -121,6 +147,10 @@ - (void)authorizeWithFBAppAuth:(BOOL)tryFBAppAuth [params setValue:scope forKey:@"scope"]; } + if (_localAppId) { + [params setValue:_localAppId forKey:@"local_client_id"]; + } + // If the device is running a version of iOS that supports multitasking, // try to obtain the access token from the Facebook app installed // on the device. @@ -132,12 +162,17 @@ - (void)authorizeWithFBAppAuth:(BOOL)tryFBAppAuth UIDevice *device = [UIDevice currentDevice]; if ([device respondsToSelector:@selector(isMultitaskingSupported)] && [device isMultitaskingSupported]) { if (tryFBAppAuth) { - NSString *fbAppUrl = [FBRequest serializeURL:kFBAppAuthURL params:params]; + NSString *scheme = kFBAppAuthURLScheme; + if (_localAppId) { + scheme = [scheme stringByAppendingString:@"2"]; + } + NSString *urlPrefix = [NSString stringWithFormat:@"%@://%@", scheme, kFBAppAuthURLPath]; + NSString *fbAppUrl = [FBRequest serializeURL:urlPrefix params:params]; didOpenOtherApp = [[UIApplication sharedApplication] openURL:[NSURL URLWithString:fbAppUrl]]; } if (trySafariAuth && !didOpenOtherApp) { - NSString *nextUrl = [NSString stringWithFormat:@"fb%@://authorize", _appId]; + NSString *nextUrl = [self getOwnBaseUrl]; [params setValue:nextUrl forKey:@"redirect_uri"]; NSString *fbAppUrl = [FBRequest serializeURL:loginDialogURL params:params]; @@ -157,7 +192,7 @@ - (void)authorizeWithFBAppAuth:(BOOL)tryFBAppAuth } /** - * A private function for parsing URL parameters. + * A function for parsing URL parameters. */ - (NSDictionary*)parseURLParams:(NSString *)query { NSArray *pairs = [query componentsSeparatedByString:@"&"]; @@ -177,7 +212,12 @@ - (NSDictionary*)parseURLParams:(NSString *)query { /////////////////////////////////////////////////////////////////////////////////////////////////// //public - +- (void)authorize:(NSArray *)permissions + delegate:(id)delegate { + [self authorize:permissions + delegate:delegate + localAppId:nil]; +} /** * Starts a dialog which prompts the user to log in to Facebook and grant @@ -198,7 +238,7 @@ - (NSDictionary*)parseURLParams:(NSString *)query { * Also note that requests may be made to the API without calling * authorize() first, in which case only public information is returned. * - * @param application_id + * @param appId * The Facebook application id, e.g. "350685531728". * @param permissions * A list of permission required for this application: e.g. @@ -209,12 +249,31 @@ - (NSDictionary*)parseURLParams:(NSString *)query { * @param delegate * Callback interface for notifying the calling application when * the user has logged in. + * @param localAppId + * localAppId is a string of lowercase letters that is + * appended to the base URL scheme used for SSO. For example, + * if your facebook ID is "350685531728" and you set localAppId to + * "abcd", the Facebook app will expect your application to bind to + * the following URL scheme: "fb350685531728abcd". + * This is useful if your have multiple iOS applications that + * share a single Facebook application id (for example, if you + * have a free and a paid version on the same app) and you want + * to use SSO with both apps. Giving both apps different + * localAppId values will allow the Facebook app to disambiguate + * their URL schemes and always redirect the user back to the + * correct app, even if both the free and the app is installed + * on the device. + * localAppId is supported on version 3.4 and above of the Facebook + * app. If the user has an older version of the Facebook app + * installed and your app uses localAppId parameter, the SDK will + * proceed as if the Facebook app isn't installed on the device + * and redirect the user to Safari. */ - (void)authorize:(NSArray *)permissions - delegate:(id)delegate { - - [_permissions release]; - _permissions = [permissions retain]; + delegate:(id)delegate + localAppId:(NSString *)localAppId { + self.localAppId = localAppId; + self.permissions = permissions; _sessionDelegate = delegate; @@ -240,7 +299,7 @@ - (void)authorize:(NSArray *)permissions */ - (BOOL)handleOpenURL:(NSURL *)url { // If the URL's structure doesn't match the structure used for Facebook authorization, abort. - if (![[url absoluteString] hasPrefix:[NSString stringWithFormat:@"fb%@://authorize", _appId]]) { + if (![[url absoluteString] hasPrefix:[self getOwnBaseUrl]]) { return NO; }