LoginSignup
83
81

More than 5 years have passed since last update.

SwiftでFacebookログインと情報取得の覚書

Posted at

自分が作りたいアプリのFacebookまわりの事をまとめてみました。

概要

・Facebookログイン(とログアウト)
・ログインしていない場合、ログインボタンとWelcome画面を表示
・ログインした後(もしくは既にログインしている場合)、名前とユーザ画像、Emailに友達リストをMain画面に表示
・というのを、Swiftで書いてみる

前提

1.環境
・Xcode 6.4
・Facebook SDK for iOS v4.4.0
・Swift version 1.2
・Facebook API Version 2.4

2.事前準備
・Facebook SDK for iOSのダウンロードとインストール
 ここからダウンロードして書類フォルダに解凍しておく
・My Appsの登録(ここから
 登録後にもらえるApp IDとアプリ名をメモっておく

3.注意事項
2015/8/5時点、Xcode,FacebookSDK共に英語ページからダウンロードしています。日本語ページだとちょっと古い…

作業の流れ

1.Xcode 新規プロジェクトの作成
2.プロジェクトへFacebook SDKを追加
3.AppDelegate.swiftの編集
4.Welcome画面の作成
5.Welcome画面にログイン機能をつける
6.Main画面の作成
7.Welcome画面からMain画面への遷移(既にログイン&ログイン成功)
8.Main画面にFBの情報を表示
9.Main画面にログアウト機能をつける

1. Xcode 新規プロジェクトの作成

1.1 Xcode を起動して Create a new Xcode project をクリック
スクリーンショット 2015-08-05 20.58.43.png

1.2 iOS|Application → Single View Application を選択して Next
スクリーンショット 2015-08-05 21.06.10.png

1.3 プロジェクト情報を入力
スクリーンショット 2015-08-05 21.20.22.png

Product Name: FBLoginSample
Organization Name: 所属組織や自分の名前とか(※とりあえず何でも良い)
Organization Identifier: ドメイン名を逆さにしたもの(※とりあえず何でも良い)
Language: Swift
Devices: iPhone
use CoreData: チェックはずす

1.4 プロジェクトを保存する場所を選択して Create

2. プロジェクトへFacebook SDKを追加

2.1 書類フォルダからFBSDKCoreKit.frameworkを選択して、ナビゲータの一番上あたりにドロップ
スクリーンショット 2015-08-05 21.27.41.png

2.2 Optionを設定してFinish
スクリーンショット 2015-08-05 21.28.01.png

Destination: チェックはずす(とりあえず既定値のまま。チェックしたらプロジェクトフォルダにデータがコピーされる)
Added Forders: Create Groups(とりあえず既定値)
Add to targets: FBloginSample(とりあえず既定値)

ここの設定を変えるとどうなるかとかは、とりあえず脇において既定値のままで。

2.3 FBSDKLoginKit.frameworkも同じようにして追加
スクリーンショット 2015-08-05 21.28.39.png

プロジェクトのGeneralタブの一番下、Linked Frameworks and Librariesの+ボタンから追加する方法もあります。(むしろそちらが正しいやり方かも??)

2.4 Supporting FilesフォルダのInfo.plistに App ID とアプリ名を登録
スクリーンショット 2015-08-06 1.17.33.png

FacebookAppID : 事前準備でメモった App ID
FacebookDisplayName :事前準備でメモった アプリ名
URL types | item 0 | URL Schemes | item 0 : fb + App ID

詳しくはFacebook Developer CenterConfigure the .plist参照

3.AppDelegate.swiftの編集

3.1 FBSDKCoreKitをimportする

AppDelegate.swift
import FBSDKCoreKit

SDK v4.1からimport文だけで使えるようになりました。(一番下のもろもろ参照)

3.2 func applicationとapplicationDidBecomeActiveを編集

AppDelegate.swift
    func application(application: UIApplication,didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
            return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
    }

    func application(application: UIApplication,openURL url: NSURL,sourceApplication: String?,annotation: AnyObject?) -> Bool {
            return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
    }

    func applicationDidBecomeActive(application: UIApplication) {
        FBSDKAppEvents.activateApp()
    }

おまじないみたいなモノと思いコピペで。

4.Welcome画面の作成

4.1 ViewController.swiftをWelcomeViewController.swiftにリネーム
ファイル名の変更にあわせてclass名も変更する
スクリーンショット 2015-08-06 0.26.17.png

4.2 Main.Storybordを開き View Controllerを選択する。
右パネル identity inspectorを選択し、Custom Classを4.1で編集したWelcomeView Controllerに変更する
スクリーンショット 2015-08-07 15.19.54.png

5.Welcome画面にログイン機能をつける

5.1.FBSDKCoreKit, FBSDKLoginKitのインポート記述を追記する 

WelcomeViewController.swift
import FBSDKCoreKit
import FBSDKLoginKit

5.2 FBSDKLoginButtonDelegateを追加
5.2.1 WelcomeViewControllerのclass定義にFBSDKLoginButtonDelegateを追加する

WelcomeViewController.swift
class WelcomeViewController: UIViewController, FBSDKLoginButtonDelegate {

5.2.2 func loginButtonとfunc loginButtonDidLogOutを追加する

WelcomeViewController.swift
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    //ログインボタンが押された時の処理。Facebookの認証とその結果を取得する
    func loginButton(loginButton: FBSDKLoginButton!,didCompleteWithResult
                    result: FBSDKLoginManagerLoginResult!, error: NSError!) {
            println("User Logged In")

            if ((error) != nil)
            {
                //エラー処理
            } else if result.isCancelled {
                //キャンセルされた時
            } else {
                //必要な情報が取れていることを確認(今回はemail必須)
                if result.grantedPermissions.contains("email")
                {
                // 次の画面に遷移(後で)
                }
            }
    }

    //ログアウトボタンが押された時の処理
    func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {
        println("User Logged Out")
    }

5.3 ログイン状態のチェック
func viewDidAppearにログイン状態の確認処理を書く。
 ・ログイン状態の場合→次の画面(この次に作るメイン画面)を表示
 ・未ログイン状態→ログイン画面を表示して、Facebook認証でログインする
viewDidLoadではないです。viewDidLoadに書くとログインをスキップして次を表示する際にエラー(表示終わっていないのに次の画面呼ぶのはダメよ…みたいな)がでるので。

WelcomeViewController.swift
    override func viewDidAppear(animated: Bool) {
        if (FBSDKAccessToken.currentAccessToken() != nil) {
            println("User Already Logged In")
            //後で既にログインしていた場合の処理(メイン画面へ遷移)を書く
       } else {
            println("User not Logged In")
            let loginView : FBSDKLoginButton = FBSDKLoginButton()
            self.view.addSubview(loginView)
            loginView.center = self.view.center
            loginView.readPermissions = ["public_profile", "email", "user_friends"]
            loginView.delegate = self
        }
    }

5.4 ここで試しに起動してみる。
Login with Facebookボタンが表示される→Facebookログイン画面が表示される→(メールアドレスとパスワードを入力する。開発登録していないユーザで入るとエラーになる)→情報へのアクセス許可画面→(ログイン)→ログアウトボタンが表示される→ログアウト→はじめに戻る

スクリーンショット 2015-08-10 1.11.19.jpg

6.Main画面の作成

6.1 ログインした後、遷移させる画面を作る。Main.Storybordを開き、ViewControllerをキャンバス上にドラッグ&ドロップする
スクリーンショット 2015-08-10 1.56.15.png

6.2 作ったViewControllerにFacebookから取得した情報を表示するコンポーネントを追加。
スクリーンショット 2015-08-10 1.52.10.png

Identity Inspectorを選択しRestracion IDを入力する

Label : Welcome(固定値)
UIImageView : userImage (プロフィール写真用)
Label : currentUserName(名前を表示する用)
Label : currentUserEmail(emailを表示する用)
Button : Logout(ログアウトボタン)

7.Welcome画面からMain画面への遷移(既にログイン&ログイン成功)

7.1 segueを作る
WelcomeViewControllerを選択し、Controlキーを押しながらMain画面をクリックする(開発を始めた頃、Commandキーを押しながらSegueを作ろうとして指定された通りに線が出ないんだけど!と悩んだのは内緒です)
スクリーンショット 2015-08-11 0.07.37.png

Segueの選択画面が表示されるので present modally を選択する
スクリーンショット 2015-08-11 0.08.02.png

SegueのAttiributes Inspectorを選択し、Identifierを入力する
スクリーンショット 2015-08-11 0.17.31.png

Identifier : ShowMain

7.2 Welcome画面からの遷移を記述する。
起動した時に既にログインしていた場合と、ログイン画面から問題なく認証できた場合に飛ぶ部分を書く。具体的には、5.2.2の「// 次の画面に遷移(後で)」と、5.3の「//後で既にログインしていた場合の処理(メイン画面へ遷移)を書く」のコメント行をperformSegueWithIdentifierで遷移するように書き換える

WelcomeViewController.swift
    override func viewDidAppear(animated: Bool) {
        if (FBSDKAccessToken.currentAccessToken() != nil) {
            println("User Already Logged In")
            self.performSegueWithIdentifier("showMain", sender: self)
...
WelcomeViewController.swift
...
    if result.grantedPermissions.contains("email"){
        self.performSegueWithIdentifier("showMain", sender: self)
    }
...         

8.Main画面にFBの情報を表示する

8.1 MainViewController.swiftを新規作成し、6.1で作ったViewControllerに紐付ける
8.2 FBSDKCoreKit, FBSDKLoginKitのインポート記述を追記する 

MainViewController.swift
import FBSDKCoreKit
import FBSDKLoginKit

8.3 写真用のイメージと名前とemailをMainViewController.swiftで使えるようにする。
Main.StoryboardのUIImageを選択し、Controlキーを押しながらMainViewController.Swiftの上にドロップ。
スクリーンショット 2015-08-11 1.06.26.png

ダイアログが表示されるので、Connectionを設定する。名前とemailも同様に。
スクリーンショット 2015-08-11 1.07.06.png

結果として、この3行がMainViewController.swiftに追加される

MainViewController.swift
    @IBOutlet weak var currentUserName: UILabel!
    @IBOutlet weak var currentUserEmail: UILabel!
    @IBOutlet weak var userImage: UIImageView!

8.4 FBから取得してきたデータを格納するフィールドを宣言

MainViewController.swift
    @IBOutlet weak var currentUserName: UILabel!
    @IBOutlet weak var currentUserEmail: UILabel!
    @IBOutlet weak var userImage: UIImageView!

    var userProfile : NSDictionary!

8.5 画面表示時(viewDidLoad)に、FBからデータ取ってきて表示する(returnUserData)

MainViewController.swift
    override func viewDidLoad() {
        super.viewDidLoad()
        returnUserData()
      }

MainViewController.swift
   func returnUserData()
    {
        let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me",
            parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"])
            graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
            if ((error) != nil)
            {
                // エラー処理
                println("Error: \(error)")
            }
            else
            {
                // プロフィール情報をディクショナリに入れる
                self.userProfile = result as! NSDictionary
                println(self.userProfile)

                // プロフィール画像の取得(よくあるように角を丸くする)
                let profileImageURL : String = self.userProfile.objectForKey("picture")?.objectForKey("data")?.objectForKey("url") as! String
                var profileImage = UIImage(data: NSData(contentsOfURL: NSURL(string: profileImageURL)!)!)
                self.userImage.clipsToBounds = true
                self.userImage.layer.cornerRadius = 60
                self.userImage.image = self.trimPicture(profileImage!)

                //名前とemail

                self.currentUserName.text = self.userProfile.objectForKey("name") as? String
                self.currentUserEmail.text = self.userProfile.objectForKey("email") as? String

                }
        })

    }
    func trimPicture(rawPic:UIImage) -> UIImage {
        var rawImageW = rawPic.size.width
        var rawImageH = rawPic.size.height

        var posX = (rawImageW - 200) / 2
        var posY = (rawImageH - 200) / 2
        var trimArea : CGRect = CGRectMake(posX, posY, 200, 200)

        var rawImageRef:CGImageRef = rawPic.CGImage
        var trimmedImageRef = CGImageCreateWithImageInRect(rawImageRef, trimArea)
        var trimmedImage : UIImage = UIImage(CGImage : trimmedImageRef)!
        return trimmedImage
    }

Facebook API Version 2.3までは、parametersを細かく指定しなくてもemailは取得できていたみたいですが、2.4から個別に書かないとダメになりました。IDと名前しか戻ってきません。

9.Main画面にログアウト機能をつける(成功したらWelcome画面に戻る)

Main.StoryboardのLogoutボタンを選択し、Controlキーを押しながらMainViewController.Swiftの上にドロップ。ダイアログが表示されるので、Accionを設定する。

スクリーンショット 2015-08-11 1.32.25.png

connectionの設定の部分をoutletからActionに変更する。これも引っかかりました…。

MainViewController.swift

    @IBAction func logout(sender: AnyObject) {
        let loginManager : FBSDKLoginManager = FBSDKLoginManager()
        loginManager.logOut()
        self.dismissViewControllerAnimated(true, completion: nil)
    }

10.完成!

もろもろ

・最新のFacebook SDK v4.1からSwiftがネイティブサポートされ、Bridging headerが不要になりました。(=swiftに直接使うライブラリをimportすればOK)

・Facebookの仕様変更で、アプリを利用している友達しか一覧が取れません。多少の裏技はあるみたいですが、正攻法では難しいみたいです。確認するためには開発仲間を巻き込みましょう……。Sunday In The Parkさんの記事が大変参考になりました。で、作っても友達が表示されないので今回は実装をスキップしました。

・作ったものはGithubに置きました。実行前にFacebookSDKをプロジェクトに追加してください。

・間違ってるとか、こっちの方が良いんじゃ?などの指摘ツッコミ大歓迎。画面がチラチラするのが気になるので誰か良い方法教えてくださいm(__)m

83
81
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
83
81