From 3edfc229759a74321ee79d68c1f09a034563471d Mon Sep 17 00:00:00 2001 From: Igor Khmurets Date: Thu, 10 Jul 2014 18:00:20 +0200 Subject: [PATCH] [ios] Abstract Facebook login support --- iphone/Maps/AccountManager.h | 33 ++++ iphone/Maps/AccountManager.m | 191 +++++++++++++++++++++ iphone/Maps/Maps.xcodeproj/project.pbxproj | 24 ++- 3 files changed, 244 insertions(+), 4 deletions(-) create mode 100644 iphone/Maps/AccountManager.h create mode 100644 iphone/Maps/AccountManager.m diff --git a/iphone/Maps/AccountManager.h b/iphone/Maps/AccountManager.h new file mode 100644 index 0000000000..bdc5b5598d --- /dev/null +++ b/iphone/Maps/AccountManager.h @@ -0,0 +1,33 @@ + +#import +#import + +@interface PostMessage : NSObject + +@property (nonatomic) NSString * name; +@property (nonatomic) NSString * info; +@property (nonatomic) NSString * link; + +@end + + +@implementation PostMessage + +@end + + +typedef NS_ENUM(NSUInteger, AccountType) +{ + AccountTypeFacebook, + AccountTypeGooglePlus +}; + +@interface AccountManager : NSObject + +- (void)loginToAccountType:(AccountType)type completion:(void (^)(BOOL success))block; +- (void)postMessage:(PostMessage *)message toAccountType:(AccountType)type completion:(void (^)(BOOL success))block; + ++ (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; ++ (void)applicationDidBecomeActive:(UIApplication *)application; + +@end diff --git a/iphone/Maps/AccountManager.m b/iphone/Maps/AccountManager.m new file mode 100644 index 0000000000..0dfc89ef58 --- /dev/null +++ b/iphone/Maps/AccountManager.m @@ -0,0 +1,191 @@ + +#import "AccountManager.h" + +@implementation AccountManager + +#pragma mark - Posting + +- (void)postMessage:(PostMessage *)message toAccountType:(AccountType)type completion:(void (^)(BOOL success))block; +{ + switch (type) + { + case AccountTypeFacebook: + { + [self postMessage:message toFacebookAndCheckPermissionsWithCompletion:block]; + break; + } + case AccountTypeGooglePlus: + { + break; + } + } +} + +- (void)postMessage:(PostMessage *)message toFacebookAndCheckPermissionsWithCompletion:(void (^)(BOOL))block +{ + if ([self hasPublishPermissionsForFacebook]) + { + [self postMessage:message toFacebookWithCompletion:^(BOOL success) { + block(success); + }]; + } + else + { + [[FBSession activeSession] requestNewPublishPermissions:@[@"publish_actions"] defaultAudience:FBSessionDefaultAudienceFriends completionHandler:^(FBSession * session, NSError * error) { + if (!error && [self hasPublishPermissionsForFacebook]) + { + [self postMessage:message toFacebookWithCompletion:^(BOOL success) { + block(success); + }]; + } + else + { + block(NO); + } + }]; + } +} + +- (void)postMessage:(PostMessage *)message toFacebookWithCompletion:(void (^)(BOOL))block +{ + FBLinkShareParams * parameters = [[FBLinkShareParams alloc] init]; + parameters.name = message.name; + parameters.link = [NSURL URLWithString:message.link]; + + if ([FBDialogs canPresentShareDialogWithParams:parameters]) + { + [FBDialogs presentShareDialogWithParams:parameters clientState:nil handler:^(FBAppCall * call, NSDictionary * results, NSError * error) { + block(!error); + }]; + } + else + { + NSMutableDictionary * parameters = [[NSMutableDictionary alloc] init]; + if (message.name) + parameters[@"name"] = message.name; + if (message.link) + parameters[@"link"] = message.link; + if (message.info) + parameters[@"description"] = message.info; + + [FBWebDialogs presentFeedDialogModallyWithSession:nil parameters:parameters handler:^(FBWebDialogResult result, NSURL * resultURL, NSError * error) { + block(!error && result != FBWebDialogResultDialogNotCompleted); + }]; + } +} + +- (BOOL)hasPublishPermissionsForFacebook +{ + return [[FBSession activeSession].permissions containsObject:@"publish_actions"]; +} + +#pragma mark - Logining + +- (void)loginToAccountType:(AccountType)type completion:(void (^)(BOOL))block +{ + switch (type) + { + case AccountTypeFacebook: + { + if ([FBSession activeSession].state != FBSessionStateOpen && [FBSession activeSession].state != FBSessionStateOpenTokenExtended) + [FBSession openActiveSessionWithReadPermissions:@[@"public_profile"] allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState state, NSError *error) { + block(!error && state == FBSessionStateOpen); + }]; + break; + } + case AccountTypeGooglePlus: + { + break; + } + } +} + ++ (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation +{ + [[FBSession activeSession] setStateChangeHandler:^(FBSession * session, FBSessionState state, NSError * error) { +// [self sessionStateChanged:session state:state error:error]; + }]; + + if ([FBAppCall handleOpenURL:url sourceApplication:sourceApplication]) + return YES; + + return NO; +} + ++ (void)applicationDidBecomeActive:(UIApplication *)application +{ + [FBAppCall handleDidBecomeActive]; +} + + +// FACEBOOK ERROR HANDLING LOGIC. KEEP FOR TESTING + +//// This method will handle ALL the session state changes in the app +//+ (void)sessionStateChanged:(FBSession *)session state:(FBSessionState)state error:(NSError *)error +//{ +// // If the session was opened successfully +// if (!error && state == FBSessionStateOpen) +// { +// NSLog(@"Session opened"); +// // Show the user the logged-in UI +// return; +// } +// if (state == FBSessionStateClosed || state == FBSessionStateClosedLoginFailed) +// { +// // If the session is closed +// NSLog(@"Session closed"); +// // Show the user the logged-out UI +// } +// +// // Handle errors +// if (error) +// { +// NSLog(@"Error"); +// NSString *alertText; +// NSString *alertTitle; +// // If the error requires people using an app to make an action outside of the app in order to recover +// if ([FBErrorUtility shouldNotifyUserForError:error] == YES) +// { +// alertTitle = @"Something went wrong"; +// alertText = [FBErrorUtility userMessageForError:error]; +//// [self showMessage:alertText withTitle:alertTitle]; +// } +// else +// { +// +// // If the user cancelled login, do nothing +// if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryUserCancelled) +// { +// NSLog(@"User cancelled login"); +// +// // Handle session closures that happen outside of the app +// } +// else if ([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryAuthenticationReopenSession) +// { +// alertTitle = @"Session Error"; +// alertText = @"Your current session is no longer valid. Please log in again."; +//// [self showMessage:alertText withTitle:alertTitle]; +// +// // Here we will handle all other errors with a generic error message. +// // We recommend you check our Handling Errors guide for more information +// // https://developers.facebook.com/docs/ios/errors/ +// } +// else +// { +// //Get more error information from the error +// NSDictionary * errorInformation = [[[error.userInfo objectForKey:@"com.facebook.sdk:ParsedJSONResponseKey"] objectForKey:@"body"] objectForKey:@"error"]; +// +// // Show the user an error message +// alertTitle = @"Something went wrong"; +// alertText = [NSString stringWithFormat:@"Please retry. \n\n If the problem persists contact us and mention this error code: %@", [errorInformation objectForKey:@"message"]]; +//// [self showMessage:alertText withTitle:alertTitle]; +// } +// } +// // Clear this token +// [FBSession.activeSession closeAndClearTokenInformation]; +// // Show the user the logged-out UI +//// [self userLoggedOut]; +// } +//} + +@end diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index 3498a97f76..0e384c181d 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -24,6 +24,8 @@ 972CDCC61887F1B7006641CA /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 972CDCC51887F1B7006641CA /* CFNetwork.framework */; }; 97354B65196AF97200352536 /* PlacePageRoutingCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97354B64196AF97200352536 /* PlacePageRoutingCell.m */; }; 97354B66196AF97200352536 /* PlacePageRoutingCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 97354B64196AF97200352536 /* PlacePageRoutingCell.m */; }; + 97354B6E196EDD3A00352536 /* AccountManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 97354B6D196EDD3A00352536 /* AccountManager.m */; }; + 97354B6F196EDD3F00352536 /* AccountManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 97354B6D196EDD3A00352536 /* AccountManager.m */; }; 97387546184E475000170BC4 /* MessageComposeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 97387545184E475000170BC4 /* MessageComposeViewController.m */; }; 97387547184E475000170BC4 /* MessageComposeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 97387545184E475000170BC4 /* MessageComposeViewController.m */; }; 974386D91934CBAC00FD5659 /* FacebookSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 974386D81934CBAC00FD5659 /* FacebookSDK.framework */; }; @@ -1357,6 +1359,8 @@ 972CDCC51887F1B7006641CA /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; 97354B63196AF97200352536 /* PlacePageRoutingCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlacePageRoutingCell.h; sourceTree = ""; }; 97354B64196AF97200352536 /* PlacePageRoutingCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlacePageRoutingCell.m; sourceTree = ""; }; + 97354B6C196EDD3A00352536 /* AccountManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AccountManager.h; sourceTree = ""; }; + 97354B6D196EDD3A00352536 /* AccountManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AccountManager.m; sourceTree = ""; }; 97387544184E475000170BC4 /* MessageComposeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageComposeViewController.h; sourceTree = ""; }; 97387545184E475000170BC4 /* MessageComposeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessageComposeViewController.m; sourceTree = ""; }; 974386D81934CBAC00FD5659 /* FacebookSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = FacebookSDK.framework; sourceTree = ""; }; @@ -1469,8 +1473,8 @@ EDB811A1175E1A9C00E36BF2 /* TwoButtonsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TwoButtonsView.h; sourceTree = ""; }; EDB811A2175E1A9C00E36BF2 /* TwoButtonsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TwoButtonsView.m; sourceTree = ""; }; EDBB18B716972B0600AF0742 /* libzlib.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libzlib.a; sourceTree = ""; }; - EDC5C541175F2CA600420E92 /* ShareActionSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShareActionSheet.h; sourceTree = ""; }; - EDC5C542175F2CA600420E92 /* ShareActionSheet.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ShareActionSheet.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + EDC5C541175F2CA600420E92 /* ShareActionSheet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ShareActionSheet.h; path = Classes/ShareActionSheet.h; sourceTree = ""; }; + EDC5C542175F2CA600420E92 /* ShareActionSheet.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; name = ShareActionSheet.mm; path = Classes/ShareActionSheet.mm; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; EE026F0511D6AC0D00645242 /* classificator.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = classificator.txt; path = ../../data/classificator.txt; sourceTree = SOURCE_ROOT; }; EE1201FF11CD464100ABDD5D /* libbase.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libbase.a; sourceTree = SOURCE_ROOT; }; EE12020011CD464100ABDD5D /* libcoding.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libcoding.a; sourceTree = SOURCE_ROOT; }; @@ -2230,8 +2234,6 @@ EED10A4411F78D120095FAD4 /* MapViewController.mm */, FAF457E415597BC100DCCC49 /* Framework.h */, FAF457E615597D4600DCCC49 /* Framework.cpp */, - EDC5C541175F2CA600420E92 /* ShareActionSheet.h */, - EDC5C542175F2CA600420E92 /* ShareActionSheet.mm */, 97DEA09018D706C300C5F963 /* Common.h */, ); path = Classes; @@ -2252,6 +2254,7 @@ CB252D6816FF82C8001E41E9 /* Statistics */, FA36B8011540388B004560CC /* Bookmarks */, FA34BEC71338D6DB00FFB2A7 /* Common */, + 97354B6B196EDCE200352536 /* Login & sharing */, FA6E1F1B124E6B2800F59149 /* Platform */, 080E96DDFE201D6D7F000001 /* Classes */, 974726401832306C006B7CB7 /* Categories */, @@ -2324,6 +2327,17 @@ name = Frameworks; sourceTree = ""; }; + 97354B6B196EDCE200352536 /* Login & sharing */ = { + isa = PBXGroup; + children = ( + EDC5C541175F2CA600420E92 /* ShareActionSheet.h */, + EDC5C542175F2CA600420E92 /* ShareActionSheet.mm */, + 97354B6C196EDD3A00352536 /* AccountManager.h */, + 97354B6D196EDD3A00352536 /* AccountManager.m */, + ); + name = "Login & sharing"; + sourceTree = ""; + }; 974726401832306C006B7CB7 /* Categories */ = { isa = PBXGroup; children = ( @@ -4473,6 +4487,7 @@ 9789DB56188D5E2A007C6FAE /* InAppMessagesManager.mm in Sources */, 9778E99D191A5B6600AD850A /* BookmarkDescriptionVC.mm in Sources */, 97387546184E475000170BC4 /* MessageComposeViewController.m in Sources */, + 97354B6E196EDD3A00352536 /* AccountManager.m in Sources */, 97C98522186AE3CF00AF7E9E /* AppInfo.mm in Sources */, 978F9242183B660F000D6C7C /* SelectableCell.m in Sources */, CB252D6F16FF82C9001E41E9 /* Statistics.mm in Sources */, @@ -4542,6 +4557,7 @@ 97387547184E475000170BC4 /* MessageComposeViewController.m in Sources */, 97C98523186AE3CF00AF7E9E /* AppInfo.mm in Sources */, 978F9243183B660F000D6C7C /* SelectableCell.m in Sources */, + 97354B6F196EDD3F00352536 /* AccountManager.m in Sources */, 97A0EEFB192F3B43009B2779 /* BottomMenu.mm in Sources */, CB252D7016FF82C9001E41E9 /* Statistics.mm in Sources */, 9778E99E191A5B6600AD850A /* BookmarkDescriptionVC.mm in Sources */,