LoginSignup
32
30

More than 5 years have passed since last update.

Twitter APIを使ってログイン・ツイート取得をしよう

Last updated at Posted at 2015-09-04

Loginの処理を作ろう

前回作ったTwitterサンプルを利用して、実際のアカウントでログイン処理を実装しよう

こちらが前回作ったもの

twitter_sample_image.jpg

これをベースに実際のログイン機能を加えていきます。

事前に以下の準備しておきましょう

  • 第3回授業までのプロジェクト用意
  • Twitterアカウント作成
  • できればiPhoneの設定からTwitterアカウントを設定

3回目までの授業プロジェクトを持っていない人は

下記のGitHubのURLからファイルを落としておきましょう。
https://github.com/hayate1996/twitter_sample_03

ファイルのダウンロードは、右下の"Download ZIP"から落とすことができます。

Screen Shot 2015-09-04 at 1.00.53 PM.png

Twitterアカウントをまだ作ってない人は

Twitterアカウントを持っていない人は、以下の手順で作成しましょう。
Twitterの公式ページへアクセスして、新規作成をクリックします。
Screen Shot 2015-08-26 at 2.49.57 AM.png

新規作成をクリックすると下記の画面があるので、登録するアカウント名や自分のメールアドレスを入力しましょう。
※ 下記は記入例です。

Screen Shot 2015-08-26 at 3.02.10 AM.png

すると、アカウントが作成されて認証用のメールアドレスが届くので認証すれば終わりです。電話番号の入力はスキップできます。

登録が終わったら、レコメンドなどを利用して有名人や友達のアカウントをフォローしておきましょう。

iPhoneに登録したアカウントを表示・選択しよう

それでは、iPhoneに登録したアカウントのデータ取得をする部分の実装をしていきます。
アカウントのデータ取得は、基本的にプログラムを書いて実装していきます。

アカウントのデータを取得するには、Twitterが提供しているAPIを利用します。APIを利用するために、iOSで提供しているAccountフレームワークとSocialフレームワークの2つをプロジェクトに追加します。

フレームワーク追加

1: ナビゲーションエリアで一番上に表示されているプロジェクトファイルを選択します。

Screen Shot 2015-08-26 at 3.40.57 AM.png

2: コーディングエリアのタブから"Build Phase"を選択します。

Screen Shot 2015-08-26 at 3.41.09 AM.png

3: コーディングエリアに表示されたリストの"Link Binary With Libraries"の▶︎をクリックして展開します。

Screen Shot 2015-08-26 at 3.41.29 AM.png

4: "+"ボタンからフレームワークを追加します。

Screen Shot 2015-08-26 at 3.41.36 AM.png

5: 検索バーに"Account"と入力してAccount.Frameworkを選択した状態で"Add"をします。

Screen Shot 2015-08-26 at 3.42.03 AM.png

6: すると、"Link Binary With Libraries"にAccount.Frameworkが追加されています。同じ手順でSocial.Frameworkも追加をしましょう。

Screen Shot 2015-08-26 at 3.42.21 AM.png

コーディング

先ほどプロジェクトに追加したAccountフレームワークをViewControllerで読み込みましょう。読み込むには"import"を使います。

import UIKit
import Accounts   // 追加

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
/*
    省略
    ...
*/
}

デバイスに登録したTwitterアカウントを取得して表示するための変数を定義します。accountsListは削除します。

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    var accountStore = ACAccountStore()   // 追加
    var twAccount = ACAccount()           // 追加
    var accounts = [ACAccount]()          // 追加

/*
    省略
    ...
*/
}

viewDidLoadからaccountsListの初期化を削除します。

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    /* 省略 */

    // 変更
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    /* 省略 */
}

デバイスからTwitterのアカウント情報を読み込んで、アカウントのリストを表示します。

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    /* 省略 */
    @IBAction func tappedLoginButton(sender: AnyObject) {
        /* 省略 */
    }

    // 追加
    /* iPhoneに設定したTwitterアカウントの情報を取得する */
    func getTwitterAccountsFromDevice(){
        let accountType = accountStore.accountTypeWithAccountTypeIdentifier(ACAccountTypeIdentifierTwitter)
        accountStore.requestAccessToAccountsWithType(accountType, options: nil) { (granted:Bool, aError:NSError?) -> Void in

            // アカウント取得に失敗したとき
            if let error = aError {
                println("Error! - \(error)")
                return;
            }

            // アカウント情報へのアクセス権限がない時
            if !granted {
                println("Cannot access to account data")
                return;
            }

            // アカウント情報の取得に成功
            self.accounts = self.accountStore.accountsWithAccountType(accountType) as! [ACAccount]
            self.showAndSelectTwitterAccountWithSelectionSheets()
        }
    }
    /* 省略 */
}

ログインするアカウントを選択した後のタイムライン画面への遷移処理を追加します。

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    /* 省略 */
    func selectTwitterAccountsFromDevice(){
         /* 省略 */
    }

    // 追加
    /* iPhoneに設定したTwitterアカウントの選択画面を表示する */
    func showAndSelectTwitterAccountWithSelectionSheets() {

        // アクションシートの設定
        var alertController = UIAlertController(title: "Select Account", message: "Please select twitter account", preferredStyle: .ActionSheet)

        for account in accounts {

            alertController.addAction(UIAlertAction(title: account.username, style: .Default, handler: { (action) -> Void in
                // 選択したアカウントをtwAccountに保存
                self.twAccount = account
                self.performSegueWithIdentifier("segueTimelineViewController", sender: nil)
            }))

        }

        // キャンセルボタンは何もせずにアクションシートを閉じる
        let CanceledAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
        alertController.addAction(CanceledAction)

        // アクションシート表示
        self.presentViewController(alertController, animated: true, completion: nil)
    }
}

TimelineViewControllerに選択したアカウントを渡すための処理を追加します。

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    /* 省略 */

    /* アカウントを選択したあと、タイムライン画面へ遷移する処理 */
    func showAndSelectTwitterAccountWithSelectionSheets(accounts: [ACAccount]) {
        /* 省略 */
    }
}

Loginボタンを押したときメソッド(tappedLoginButton)の処理を変更します。

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    /* 省略 */

    //  変更
    @IBAction func tappedLoginButton(sender: AnyObject) {
         self.selectTwitterAccountsFromDevice()
    }
    /* 省略 */
}

それぞれを追加したら、シミュレーターを起動して実行してみましょう。

comp_01.png

解説

フレームワーク

今回、SocialとAccountの2つのフレームワークを利用してTwitterアカウントとタイムラインの取得を行いました。では、Frameworkとはなんでしょう?

フレームワークとは、特定の機能を使いやすくしたり、必要な機能を提供するプログラムをまとめたものです。SocialとAccountのフレームワークは、Social機能を使いやすくしてくれます。

例えば、マップのフレームワークでは

  • "GPSを使って座標を取得する"
  • "現在地から目的地へのルートを取得する"
  • "取得した座標をマップに表示する"
  • "マップのUI"などを提供します。

などを提供して、実装を助けてくれています。

タイムラインを取得して表示しよう

TimelineViewControllerにタイムラインを取得する処理を追加しましょう。

先ほどプロジェクトに追加したSocialフレームワークをTimelineViewControllerで読み込みましょう。読み込むには"import"を使います。

import UIKit
import Social     // 追加
import Accounts   // 追加

class TimelineViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource {
    let cellIdentifier = "tweetCell"
    var tweets = []   // 変更

    var twAccount = ACAccount()  // 追加

    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationItem.title = "Timeline"
        fetchTimeline()  // 追加
        tableView.contentOffset.y = -self.refreshControl!.frame.size.height //追加
        //  tweetsの初期化は削除
    }
/*
    省略
    ...
*/
}

TimelineViewControllerに選択したアカウントを渡すための処理をViewControllerに追加しましょう。

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    /* 省略 */

    // TimelineViewControllerを表示する際に選択したアカウントを渡す
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "segueTimelineViewController" {
            var vc = segue.destinationViewController as! TimelineViewController
            vc.twAccount = self.twAccount
        }
    }
}

タイムラインを取得するメソッドfetchTimeline()を追加します。

class TimelineViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource {

    /* 省略 */

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        self.performSegueWithIdentifier("showTimelineDetailViewController", sender: nil)
    }

    //  追加
    //  Twitter APIを使ってタイムラインを取得しtweetsに保存する
    func fetchTimeline() {
        let URL = NSURL(string: "https://api.twitter.com/1.1/statuses/home_timeline.json")

        let request = SLRequest(forServiceType: SLServiceTypeTwitter, requestMethod: .GET, URL: URL, parameters: nil)
        request.account = twAccount

        UIApplication.sharedApplication().networkActivityIndicatorVisible = true

        request.performRequestWithHandler { (data, response, error:NSError?) -> Void in
            UIApplication.sharedApplication().networkActivityIndicatorVisible = false

            if error != nil {
                println("Fetching Error: \(error)")
                return;
            }

            self.tweets = NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments, error: nil) as! NSArray
            dispatch_async(dispatch_get_main_queue(), {
                self.tableView.reloadData()
            })
        }
    }
}

tableView:numberOfRowsInSection:メソッドの実装を変更します

class TimelineViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource {

    /* 省略 */

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return tweets.count  //  変更
    }

    /* 省略 */
}

取得したツイートをセルにセットします。

class TimelineViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource {

    /* 省略 */

    // 変更
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        var cell = tableView.dequeueReusableCellWithIdentifier("tweetCell") as? UITableViewCell

        if cell == nil {
            cell = UITableViewCell(style: .Default, reuseIdentifier: "tweetCell")
        }

        // ↓ 変更
        let tweet = tweets[indexPath.row] as! Dictionary<String,AnyObject>
        let text = tweet["text"] as! String
        let user = tweet["user"] as! Dictionary<String,AnyObject>
        let name = user["name"] as! String
        let image = UIImage(data: NSData(contentsOfURL: NSURL(string: user["profile_image_url"] as! String)!)!)

        let aCell = cell!
        aCell.imageView?.image = image
        aCell.textLabel?.text = text
        aCell.detailTextLabel?.text = name

        return aCell
    }

    /* 省略 */
}

comp_02.png

Tips

UIAlertControllerについて

UIAlertControllerは、アラートはアクションシートを使うために提供されているクラスです。UIKit.Frameworkで提供されています。今回、アカウントの選択画面を実装するのに使用しています。

※ アクションシート
Screen Shot 2015-08-26 at 5.23.56 AM.png

※ アラート
images.png

まとめ

  1. フレームワークは特定の機能を使いやすくするプログラムの集まり
  2. フレームワークを利用するときはプロジェクト設定の"Build Phase"から追加する
  3. ユーザーごとにタイムラインを表示するために、ユーザー情報を使ってタイムラインを初期化する
32
30
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
32
30