Facebook login 連結作法
我們在開發一個 App 時,會員系統以及社群平台的連結是常見的需求。
在社群的文章發佈方面,iOS 己在 iOS 5/6 引入了 Social Framework,省去了開發者不少時間。
然而僅止於此。如果需要進一步取得 facebook 的帳號 email,還是必需要透過 Facebook SDK 才行。
本文主要參考2016年3月份的 Facebook 線上教學。由於 Facebook 會不定時修改 API, 若照著本文裡的作法發現問題時,有可能是 Facebook 官方已作變動,請務必仔細參考最新官方線上教學
1. 下載與佈署最新的 FacebookSDK
2. 到 Facebook Developer 網站註冊一個 App
這裡對於初次開發與 Facebook 連結的 iOS App developer 新手來說容易混淆,在這裡多作一些說明:
Facebook 上的 App 與 iOS App 不同,是在 Facebook 上的應用程式。
iOS App 要使用 Facebook 帳號登入,需要先在 Facebook 上註冊一個 App, 然後在 Facebook Login 過程中, iOS App 透過這個 Facebook App 來進行登入作業,其中包括了取得使用者的權限同意,例如是否同意該 App 取用我的朋友列表等等。
當然,為了要達成這個目的,iOS App 與 Facebook App 都需要作相關的設定。
先填寫 Facebook App 的名字
選擇平台:iOS
2.1 iOS App 方需要作的設定
2.1.1 加Facebook SDK Framework
將~/Documents/FacebookSDK下的 FBSDKCoreKit.Framework, FBSDKLoginKit.Framework加入 Projects 裡
2.1.2 修改 .plist 檔
在 projects 的 .plist 檔裡,新增 Facebook App 的資訊。在創建 Facebook App 的過程中,可以看到下面的xml設定
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>fb.......</string> </array> </dict> </array> <key>FacebookAppID</key> <string>.......</string> <key>FacebookDisplayName</key> <string>iOS Login Example</string>
將.plist 檔以 source code 方式開啟(點滑鼠右鍵選 source code) 將之複製至 .plist 檔裡即可
2.1.3 修改 .plist 檔 (iOS9)
在 iOS9 以上,需要增加下面的 xml 至 .plist 檔裡
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>facebook.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSThirdPartyExceptionRequiresForwardSecrecy</key> <false/> </dict> <key>fbcdn.net</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSThirdPartyExceptionRequiresForwardSecrecy</key> <false/> </dict> <key>akamaihd.net</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSThirdPartyExceptionRequiresForwardSecrecy</key> <false/> </dict> </dict> </dict> <key>LSApplicationQueriesSchemes</key> <array> <string>fbapi</string> <string>fb-messenger-api</string> <string>fbauth2</string> <string>fbshareextension</string> </array>
2.2 Facebook App 方需要作的設定
2.2.1 填入 iOS App Bundle ID
需要將 iOS App 的 Bundle ID 填入 Facebook App 的 Setting 裡
2.2.2 允許 Facebook App 讓每個人使用
需要在 App Review(App審查)裡,將 Your app is currently live and available to the public. 打開
若不打開的話,就會只有 Facebook App 的開發者自己可以使用。還有在 Roles 設定裡有設定的使用者可以使用。
3. xcode projects 使用步驟
3.1 AppDelegate.m 修改
3.1.1 import
#import <FBSDKCoreKit/FBSDKCoreKit.h> #import <FBSDKLoginKit/FBSDKLoginKit.h>
3.1.2 增加 method
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation]; }
3.2 FBSDKLoginButton 設置
Storyboard 裡增加一個 button, 並將 class 改為 FBSDKLoginButton
3.2.1 AppDelegate.didFinishLaunchingWithOptions 修改
為了要讓 Storyboard 裡的 FBSDKLoginButton 正常運作,必需要在AppDelegate.m 裡的 didFinishLaunchingWithOptions 增加一行
[FBSDKLoginButton class];
這是個蠻 trick 的作法。官方的範例並沒有使用 storyboard 而是用程式碼 new button,不過如此一來不方便使用 auto layout 。
而若使用 storyboard 將 UIButton 的 class 設為 FBSDKLoginButton 的話,在執行時會發生 Unknown class FBSDKLoginButton in Interface Builder file 的錯誤。
其簡單的解法,就是在AppDelegate.m 裡的 didFinishLaunchingWithOptions先行使用 FBSDKLoginButton 讓它載入。
3.3 import frameworks
在使用到的 .m 檔裡 import 必要的 frameworks
#import <FBSDKCoreKit/FBSDKCoreKit.h> #import <FBSDKLoginKit/FBSDKLoginKit.h>
3.4 Permission 設置
增加 button 的 IBOutlet,需要由 Storyboard 拉過來進行連結。若這個技巧尚不會的新手,請參考官方文件:Create Outlet
@property (weak, nonatomic) IBOutlet FBSDKLoginButton *fbLoginButton;
在 viewDidLoad 裡設定
self.fbLoginButton.readPermissions = @[@"public_profile", @"email", @"user_friends"];
3.5 login delegate
在 viewDidLoad 裡將 FBSDKLoginButton 的 delegate 設為自己
self.fbLoginButton.delegate=self;
3.6 處理登入結果
- (void)loginButton: (FBSDKLoginButton *)loginButton didCompleteWithResult: (FBSDKLoginManagerLoginResult *)result error: (NSError *)error { if (result.isCancelled==YES) { NSLog(@"User login canceled."); }else{ NSLog(@"grantedPermissions=%@",result.grantedPermissions); FBSDKAccessToken *token=result.token; NSLog(@"userID=%@",token.userID); NSLog(@"tokenString=%@",token.tokenString); if ([result.grantedPermissions containsObject:@"email"]) { if ([FBSDKAccessToken currentAccessToken]) { NSDictionary *param = @{@"fields" : @"email,id,name,picture.width(100).height(100)"}; [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:param] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (!error && result!=nil) { if([result isKindOfClass:[NSDictionary class]]) { NSLog(@"email=%@",result[@"email"]); [_emailLabel setText:result[@"email"]]; NSLog(@"name=%@",result[@"name"]); [_nameLabel setText:result[@"name"]]; NSString *imageStringOfLoginUser = [[[result valueForKey:@"picture"] valueForKey:@"data"] valueForKey:@"url"]; NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageStringOfLoginUser]]; self.imageView.image = [UIImage imageWithData:imageData]; } } }]; } } else { NSLog(@"Not granted"); } } if(error != nil) NSLog(@"error=%@",error); } - (void)loginButtonDidLogOut:(FBSDKLoginButton *)loginButton { }
在登入之後立即可以取得的是 userID 與 access token,不過一般來說,更常使用的是 email。
要取得 email ,必需要用這個 token 進一步的透過 FBSDKGraphRequest 來向 Facebook 詢問才能取得。
4. 範例程式
請參考 範例程式