透過簡單的實作 — fb 登入、fb 登出以及顯示取得授權的公開資訊
前置作業
使用 Facebook 登入的前置作業大同小異,單純作為紀錄的筆記,之後若有需要則可以快速參照。
【註冊為 facebook 的開發者且建立應用程式】
- 註冊為 facebook 的開發者
FB 開發者平台:https://developers.facebook.com - 建立 App:只需要 FB Login 功能可以選擇「消費者 ( Consumer ) 」類型
官方說明文件:提供一系列的操作提示說明 ( iOS 版 Facebook 登入 — 快速入門 )
【Xcode 加入第三方套件】
- 採用 SPM 安裝套件 https://github.com/facebook/facebook-ios-sdk
- 勾選 FacebookLogIn
【套件辨識碼】套件辨識碼即 App 的 Bundle ID
【啟用應用程式單一登入】
【設定專案 Info.plist】
『第一種方式:以 key 值設定』
- 新增 URL Type — URL Schemes:fb + App ID
- 新增 key
FacebookAppID
FacebookDisplayName
FacebookClientToken
LSApplicationQueriesSchemes → Array
- fbapi
- fb-messenger-share-api
『第二種方式:以 XML 程式碼設定』
在專案的 Info.plist 選擇以原始碼開啟 ( 右鍵 > Open As > Source Code )
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>fbAPP-ID</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>APP-ID</string>
<key>FacebookClientToken</key>
<string>CLIENT-TOKEN</string>
<key>FacebookDisplayName</key>
<string>APP-NAME</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-share-api</string>
</array>
打開 Keychain Sharing(鑰匙圈分享)
【設定 App — AppDelegate / SceneDelegate】
記得匯入框架 FacebookCore 方可使用 facebook 的設定,以及 App 啟動時完成 FB 的相關設定。
參考:facebook 說明文件
〖開始使用 Facebook iOS SDK-步驟 3:連結應用程式委派〗
AppDelegate.swift
// AppDelegate.swift
import UIKit
import FacebookCore@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
ApplicationDelegate.shared.application(app, open: url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String, annotation: options[UIApplication.OpenURLOptionsKey.annotation]
)
}
}
SceneDelegate.swift
記得 import FacebookCore
func scene(_ scene:UIScene, openURLContexts URLContexts:Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else { return }
ApplicationDelegate.shared.application( UIApplication.shared, open: url, sourceApplication: nil, annotation: [UIApplication.OpenURLOptionsKey.annotation] )
}
內建 Facebook 登入的按鈕
使用內建的按鈕,加上登出設定
import FacebookLoginclass ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let loginButton = FBLoginButton()
loginButton.center = view.convert(CGPoint(x: view.center.x, y: 200), from: self.view)
view.addSubview(loginButton) let manager = LoginManager()
manager.logOut()
}
}
一般自訂按鈕
【學習重點:檢查目前登入狀況】
AccessToken.current
登入用戶,nil 則為尚未取得授權userID
:使用者用戶,用於辨識目前登入用戶的 ID
if let token = AccessToken.current,
!token.isExpired {
print("\(token.userID) login")
} else {
print("not login")
}
【實作:開啟 App 後 — 判斷是否登入 facebook】
- 狀況 1(已登入):進入下一個畫面
- 狀況 2(尚未登入):停留在登入畫面,點選登入按鈕以進行登入,登入後再進入下一個畫面
if let accessToken = AccessToken.current,
!accessToken.isExpired {
print("\(accessToken.userID) login")
// 目前已經登入後要執行的程式碼...
guard let controller = self.storyboard?.instantiateViewController(withIdentifier: "\(ProfileViewController.self)") as? ProfileViewController else { return }
self.present(controller, animated: false, completion: nil)
} else {
print("not login")
}
【學習重點:設定權限】
設定取得的權限包括公開的 profile 資訊和 email
let manager = LoginManager()
manager.logIn(permissions: [.publicProfile, .email], viewController: nil) { result in
switch result {
case .success(granted: let granted, declined: let declined, token: let token):
print("success")
}
case .cancelled:
print("cancelled")
case .failed(_):
print("failed")
}
}
【學習重點:如何取得授權的資訊】
方法一:登入成功後取得相關資訊
let request = GraphRequest(graphPath: "me", parameters: ["fields": "id, email, name"])
request.start { response, result, error in
if let result = result as? [String:String] {
print(result)
}
}
方法二:透過 Profile 呼叫 loadCurrentProfile 下載使用者的 profile 資訊『大頭照、公開的 email、name』
if let _ = AccessToken.current {
Profile.loadCurrentProfile { profile, error in
if let profile = profile,
let email = profile.email,
let name = profile.name {
print(name)
print(profile.imageURL(forMode: .square, size: CGSize(width: 300, height: 300)))
}
}
}
【實作:下一個畫面 - 顯示登入 facebook 取得授權公開資訊】
- name
- 大頭照
step 1. 畫面一:自訂登入按鈕
記得匯入框架 FacebookLogin
@IBAction func facebookLogIn(_ sender: UIButton) {
let manager = LoginManager()
manager.logIn(permissions: [.publicProfile, .email], viewController: nil) { result in
switch result {
case .success(granted: let granted, declined: let declined, token: let token):
print("success")
let request = GraphRequest(graphPath: "me", parameters: ["fields": "id, email, name"])
request.start { response, result, error in
if let result = result as? [String:String] {
print(result)
guard let controller = self.storyboard?.instantiateViewController(withIdentifier: "\(ProfileViewController.self)") as? ProfileViewController else { return }
self.present(controller, animated: false, completion: nil)
}
}
case .cancelled:
print("cancelled")
case .failed(_):
print("failed")
}
}
}
step2. 畫面二:取得資訊、登出 facebook
import UIKit
import FacebookLoginclass ProfileViewController: UIViewController {@IBOutlet weak var emailLabel: UILabel! {
didSet {
emailLabel.numberOfLines = 0
}
}
@IBOutlet weak var IDLabel: UILabel!
@IBOutlet weak var photoImageView: UIImageView!override func viewDidLoad() {
super.viewDidLoad()if let _ = AccessToken.current {
Profile.loadCurrentProfile { profile, error in
if let profile = profile,
let email = profile.email,
let name = profile.name {
print(name)
print(profile.imageURL(forMode: .square, size: CGSize(width: 300, height: 300)))
self.emailLabel.text = "email: \(email)"
self.IDLabel.text = "name: \(name)"
self.photoImageView.load(url: profile.imageURL(forMode: .square, size: CGSize(width: 300, height: 300))!)
}
}
}
}
@IBAction func facebookSignOut(_ sender: UIButton) {
let manager = LoginManager()
manager.logOut()
dismiss(animated: true, completion: nil)
}}
extension UIImageView {
func load(url: URL) {
DispatchQueue.global().async { [weak self] in
if let data = try? Data(contentsOf: url) {
if let image = UIImage(data: data) {
DispatchQueue.main.async {
self?.image = image
}
}
}
}
}
}
其他
【開放所有帳號可以登入】
尚未做其他設定之前,只有開發者可以登入
在開發者頁面
- 設定 Privacy Policy URL、User data deletion
- 將右上的 Live 開關打開
【在模擬器切換 FB 帳號】
除非透過『重置模擬器』,不然即使移除 App,模擬器仍舊存在已登入過的 facebook 紀錄則會由此登入