第10講 My Tweet
印刷を御希望の方はページ一番下の「印刷用ページ」より印刷してください。
PDFファイルとして保存したい場合も「印刷用ページ」より保存できます。
見出しに「★」マークがついた箇所は説明動画がございます。

第10講のポイント

第10講のポイント

  • 外部サービスとの連携とTwitterフレームワークの利用
  • JSONやTwitter APIの概念理解

はじめに

前回の「万歩計」では、スマートフォンの特徴とも言える加速度センサーや位置情報センサーを活用し、歩行検知や地図の表示、現在地の取得等を扱いました。
第10講の課題アプリは「My Tweet」となります。「My Tweet」は、オリジナルの簡易Twitterクライアントアプリと考えて下さい。Twitterのアカウントと連携し、アプリからTweetを投稿できるほか、自分のフォローしているユーザーのTweetがタイムライン形式で表示されるようになっています。

今回は、iOSアプリとウェブサービスの関係を捉え、それらがどのように連携しあっているかを考えていきます。



それでは、早速開発を始めて行きましょう! 

プロジェクトの立ち上げと設定

新しいアプリを作る際は、まず、新規プロジェクトを立ち上げとアプリの設定を行います。

新規プロジェクトの立ち上げ

新規プロジェクトを立ち上げます。その際、使用するテンプレートは「Single View Application」となります。



Product Name MyTweet
Company Identifier com.rainbowapps
Device Family iPhone
Use Storyboard チェックを入れる
Use Automatic Reference Counting チェックを入れる
Include Unit Tests チェックを入れる

アプリの設定

新規プロジェクトを立ち上げたら、アプリの設定を行います。ここで、アプリのアイコンやアプリの表示タイトル(Bundle Display Name)、サポートするデバイスの向き(Device Orientation)を以下のように、設定します。

外部素材のインポート

まず、今回使用する外部素材ファイルを一気にインポートしてしまいましょう。


今回使用する素材は以下の通りです。

icon.png アイコン画像


アイコン設定とサポートするデバイスの向きの設定

素材のインポートが完了したら、Project Editorを開き、アイコンをRetina Displayと書かれたエリアの上にドラッグします。
サポートするデバイスの向きとアプリの名前は以下の通り設定します。


Bundle display nameの設定

アプリの表示タイトルを決めている設定項目「Bundle Display Name」を変更します。
Project Editorの「info」タブをクリックして「Bundle Display Name」の項目を次のように変更していきます。

 Bundle Display Name MyTweet





画面のデザイン

アプリの設定が完了したら、画面のデザインを行なっていきます。

Autolayoutの無効化

画面レイアウトを3.5インチ(iPhone4S以前)と4インチ(iPhone5以降)に対応させるための設定を行います。
まずはXcode4.5からデフォルトで有効になっているAutolayoutを無効にします。
※Autolayoutはまだ不安定ですので本講座はAutolayoutを無効にして画面デザインを行っていきます。
下記のように①View Controller全体を選択し、②「File Inspector」に変更して、③「Use Autolayout」のチェックを外してください。


Navigation Bar・Bar Button Itemの設置

まずは画面上部に、Navigation Barを設置します。ライブラリーエリアから、Navigation Barを選択し、画面の上部にドラッグします。



その次に、「Tweet」ボタンをNavigation Barの右手に設置します。また、「更新」ボタンをNavigation Barの左手に設置します。




次に、「Tweet投稿」ボタンの見た目を変更します。ボタンを選択した上で、インスペクターから、今回は通常のViewの上にTable Viewを設置していきます。ライブラリーエリアから「Identifier」を「Add」に変更します。これによって、ボタンの見た目が変更されることを確認してください。



同様に、「更新ボタン」ボタンの見た目を変更します。ボタンを選択した上で、インスペクターから、今回は通常のViewの上にTable Viewを設置していきます。ライブラリーエリアから「Identifier」を「Refresh」に変更します。これによって、ボタンの見た目が変更されることを確認してください。



この後、Navigation Barのタイトルを「My Tweet」に変更します。現状で「Title」と書かれている所をダブルクリックし、書き換えます。

Table Viewの設置

次に、Table Viewを設置します。ライブラリーエリアからTable Viewを選択し、画面を一杯に広げ、「Prototype Cells」に「1」を指定します。



「RSSリーダー」の時と同様、セルのフォーマットをカスタマイズします。標準状態でもいいのですが、今回は、「Prototype Cells」と記されたエリアに2つのラベルを配置します。同時にセルの大きさも少し広げます。その際、「ツイート」と書かれたラベルの行数を「2」とします。同時に、Fontのサイズを「17」とします。



次に、これら2つのラベルにTag番号を設定します。まず、「ツイート」と書かれたラベルを選択し、インスペクターから以下のとおり、Tag番号を「1」とします。


同様に、「user」と書かれたラベルも同じようにTag番号を設定します。こちらのラベルのTag番号は「2」とします。



最後に、セルそのものの、Identifierを「TweetCell」に設定します。



これにて、画面デザインは完了となります。

外部ウェブサービスとの連携

ここでは、自作アプリと外部ウェブサービスの連携を考えていきます。またその際の手法についても解説していきます。

外部ウェブサービスの例

皆さんは、スマートフォンやタブレットなどを使う際、TwitterやFacebookの公式アプリを使ったことはありますか。また、日常的に使っているその他のアプリからTweetを投稿したり、Facebookにチェックインしたりしたことはありますか。

このように、TwitterやFacebookに代表されるウェブサービスは、様々なスマートフォンアプリや別のウェブサイトと連携できるような仕組みをもっています。また、その際に必要となる技術的な仕組みはすべて公開されています。

よって、私達でも、自由にこのようなウェブサービスと連携できるアプリを作成できるのです。

今回は、数あるウェブサービスのなかでも、Twitterに焦点をあてます。ほとんどの方はTwitterのことを聞いたことある、あるいは、使ったことがあるでしょう。Twitterはいわゆるマイクロブログサービスと呼ばれるサービスの一種で、ユーザーは140文字以内のTweet(つぶやき)を投稿できるようになっています。また、興味のあるユーザーを「フォロー」することで、一括してTweetを閲覧することができます。

外部ウェブサービスとの連携に使われる技術

Twitterをはじめとするウェブサービスと連携する手法は様々あるのですが、現段階で最も多く使われているのは、「API」と呼ばれる仕組みを用いた手法でしょう。

API(Application Programming Interface)とは、あるサービスやソフトウェアの内部システムと、第三者の作成したアプリを連携させるための仕組みを示します。Twitterの場合、Twitter APIというものを開発者に公開しています。このTwitter APIを用いることで、開発者は自分のアプリからTweetの参照や投稿が行えるようになっています。APIについて、詳しく知りたい方は是非下記ページにて調べてみて下さい。

Twitter APIは様々な機能を持っているのですが、その中でもよく使われるのが、Tweetを参照する機能です。Twitter API特定のURLにアクセスすると、JSONという形式のメッセージでTweetの一覧が返されます。JSONはシステム間でデータを交換するために使われる、非常に軽量なデータ表現形式です。おおまかな役割としては、「RSSリーダー」で扱ったXMLと同じです。ただし、XMLと大きく異なる点がいくつかあります。それを以下に示します。
  • 「名前(キー)」と「値」のペアでデータを格納・表現
  • 状況によるが、多くの場合、XMLと比較すると同じデータを少ない容量でやり取りできる
このように説明されてもイメージしづらいと思うので、実際にJSON形式のメッセージの中身を見てみましょう。ここでは例として、クラスに属する生徒の氏名(name)、年齢(age)、得意科目(subject)をやりとりする場合を考えます。

[

{“name”: “山田 太郎”, “age”: 15, “subject”: “数学”},

{“name”: “鈴木 次郎”, “age”: 14, “subject”: “国語”},

{“name”: “橋本 三郎”, “age”: 16, “subject”: “体育”},

      …クラス全員分続く…

]



このように、1つのデータのまとまりは「{}」で囲まれ、それぞれの項目は「名前(キー)」と「値」のペアになっており、カンマで区切られていることがわかるかと思います。また、同じ種類のデータの集合は「[]」で囲まれ、配列として扱われています。このように、JSON形式のメッセージは人間にとっても理解しやすく、また機械との親和性が高いことでも知られています。
JSONの概要を説明したところで、実際にTwitter APIを通してTweetを取得した時の例を以下に示します。

 [
  {
    "coordinates": null,
    "favorited": false,
    "created_at": "Fri Jul 16 16:40:34 +0000 2010",
    "truncated": false,
    "entities": { "urls": [], "hashtags": [],“user_mentions:[]},
    "text": "Walking the DOM like Huggybear.",
    "annotations": null,
    "contributors": null,
    "id": 18699620902,
    "geo": null,
    "in_reply_to_user_id": null,
    "place": null,
    "in_reply_to_screen_name": null,
    "user": {
      "name": "Kevin Lawver",
      "screen_name": "kplawver"
    …その他ユーザー情報…
    },
    "source": "web",
    "in_reply_to_status_id": null
  },
 …その他のTweet…
]

上の例は、複数のTweetを含むJSONのうち、1つのTweetに関する情報を抜粋したものです。このように、140文字のTweetに裏には、ユーザー名や場所、日時等、多くの情報が付加されている事がわかります。

1つのTweetに含まれる多数の情報のうち、いくつか重要な要素を以下に示します。
  • “created_at” … Tweetされた日時
  • “text” … Tweetの本文
  • “user”→”name” … Tweetしたユーザーの表示名
  • “user”→”screen_name” … Tweetしたユーザー名(例:@kplawyer)
このように、Twitter APIを用いることで、このようなJSON形式のメッセージでTweetを取得することができます。JSON形式のメッセージそのものは単純な文字列ですが、前述したように機械との親和性が高く、簡単にNSArrayのような配列や、後ほど説明するNSDictionaryのような「連想配列」に変換することができます。よって、Tweetをアプリのなかで処理する上では好都合といえます。

iOSとTwitterの関係

Twitter APIやJSONの説明をこれまで簡単にしましたが、実は、Twitter APIは少し扱うのは難しい側面を持っています。例えば、ユーザー自身のタイムラインを取得する場合を考えた場合、当然、ユーザー名とパスワードを用いて、本人の確認を行う必要があります。また、Twitter APIをアプリから利用する際は、「RSSリーダー」で取り扱ったようなHTTP通信を行い、JSONをパース(解析)する仕組みが必要となります。このような仕組みのコーディングは、プログラミング上級者ならともかく、初心者にとってはハードルが高いでしょう。

しかし、幸いなことに、iOS 5から「Twitterフレームワーク」というものが、iOS SDKに含まれることになりました。iOS 5では、Twitter APIとの連携の仕組みが、iOSそのものに深く組み込まれているのです。よって、開発者もTwitterフレームワークを有効活用することによって、非常に手軽にTwitterの機能を自分のアプリに組み込めるようになりました。また、iOS6からは、「ソーシャルフレームワーク」というものが組み込まれ、「Twitterフレームワーク」非推奨となりました。そのため、本テキストではソーシャルフレームワークを利用します。

iOSそのものにTwitterの仕組みが埋め込まれているのを確認するために、ホーム画面から「設定」→「Twitter」と進めて下さい。



ここから見て取れるように、Twitterのユーザー認証がiOSそのものの設定画面から行えるようになっています。これにより、開発者にとって大変な部分をiOSがすべて肩代わりすることが可能になっています。

今回の「My Tweet」では、このソーシャルフレームワークを用いて、簡単なオリジナルのTwitterクライアントをつくります。

コードの記述

Twitter APIやJSONの仕組みを簡単に説明したところで、実際にコーディングを行なっていきます。

ソーシャルフレームワークの利用準備

まずは、Twitterと連携する為のソーシャルフレームワークの利用準備から行います。以下の通り、Project Editorから「Social.framework」と「Accounts.framework」をプロジェクトに取り込みます。



次に、コードから先程のフレームワークをアクセスするために、以下の通りView Controller.hを編集します。

ViewController.h
#import <UIKit/UIKit.h>

#import <Social/Social.h>

#import <Accounts/Accounts.h>

メンバー変数の宣言

次に、メンバー変数を宣言します。以下の通り、ViewController.mを編集してください。

ViewController.m
@implementation ViewController {

    //タイムラインの最新20Tweetを保存する配列

    NSArray *tweets;

    //Table Viewインスタンス

    IBOutlet UITableView *table;

}


Tweetの取得

次に、Tweetを実際に取得するコードを実装していきます。その前に、今回用いるTwitter APIの具体的な機能について少し説明します。

今回はTwitter APIのなかでも、「GET statuses/home_timeline」というものを利用します。これは、自分がフォロー中のユーザーや、自分自身のTweetを取得するためのAPIです。通常ログインした際に,まず表示されるタイムラインをJSON形式で取得することができます。タイムラインを取得するためには、まず、ユーザー本人の認証を行った上で、以下のURLにアクセスします。そうすると、前述したJSONのフォーマットでTweetが取得できます。この他に、Twitter APIは様々な機能を提供しています。より詳しく知りたい方は是非調べてみて下さい。

それでは実際にコードを記述していきます。View Controllerに以下のようなメソッドを記述して下さい。

ViewController.m
 - (void)getTimeline {

    //Twitter APIURLを準備

    //今回は「statuses/home_timeline.json」を利用

    NSString *apiURL = @"https://api.twitter.com/1.1/statuses/home_timeline.json";


    //iOS内に保存されているTwitterのアカウント情報を取得

    ACAccountStore *store = [[ACAccountStore allocinit];

    ACAccountType *twitterAccountType = 

        [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];


    //ユーザーにTwitterの認証情報を使うことを確認

    [store requestAccessToAccountsWithType:twitterAccountType 

                options:nil 

                completion:^(BOOL granted, NSError *error) {

        //ユーザーが拒否した場合

        if (!granted) {

            NSLog(@"Twitterへの認証が拒否されました。");

            [self alertAccountProblem];

        //ユーザーの了解が取れた場合

        } else {

            //デバイスに保存されているTwitterのアカウント情報をすべて取得

            NSArray *twitterAccounts = [store accountsWithAccountType:twitterAccountType];

            //Twitterのアカウントが1つ以上登録されている場合

            if ([twitterAccounts count] > 0) {

                //0番目のアカウントを使用

                ACAccount *account = [twitterAccounts objectAtIndex:0];

                //認証が必要な要求に関する設定

                NSMutableDictionary *params = [[NSMutableDictionary allocinit];

                [params setObject:@"1" forKey:@"include_entities"];

                //リクエストを生成

                NSURL *url = [NSURL URLWithString:apiURL];

                SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter 

                                        requestMethod:SLRequestMethodGET 

                                        URL:url parameters:params];

                //リクエストに認証情報を付加

                [request setAccount:account];

                //ステータスバーのActivity Indicatorを開始

                [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

                //リクエストを発行

                [request performRequestWithHandler:^(

                        NSData *responseData,

                        NSHTTPURLResponse *urlResponse,

                        NSError *error) {

                    //Twitterからの応答がなかった場合

                    if (!responseData) {

                        // inspect the contents of error 

                        NSLog(@"response error: %@", error); 

                        //Twitterからの返答があった場合

                    } else {

                        //JSONの配列を解析し、TweetNSArrayの配列に入れる

                        NSError *jsonError;

                        tweets = [NSJSONSerialization JSONObjectWithData:responseData 

                                    optionsNSJSONReadingMutableLeaves error:&jsonError];

                        //Tweet取得完了に伴い、Table Viewを更新

                        [self refreshTableOnFront];

                    }

                }];

            } else {

                [self alertAccountProblem];

            }

        } 

    }];

}


今回のコードは少し長いですが、その処理の流れを説明すると、以下のようになります。
  • iOS内に保存されているアカウント情報の参照をする(ユーザーの意思確認も同時にとる)
  • 各種アカウント情報のうち、Twitterのアカウント情報(ユーザー名とパスワード)をすべて取得し、その中で最初(0番目)のアカウントを利用する(iOSの場合、複数のTwitterアカウントを登録可能)
  • APIのURLをもとに、リクエスト(Tweetの要求書)を生成する
  • リクエストに認証情報を付加し、JSONをダウンロード
  • JSONは配列として最新20個のTweetを含んでいるので、それを分解し、NSArray型の「tweets」に格納
  • 取得したTweetをもとに、Table Viewを更新
コードこそ少し長いものの、順を追ってみると、そこまで複雑な処理ではないことがわかるかと思います。

このなかで、何点か指摘すべき箇所があります。このメソッドは、iOS内にTwitterのアカウント情報が保存されていることを前提としています。もし、アカウントが1つも設定されていない場合は、当然のことながら、Twitterにアクセスすることはできません。そのような場合は、「[twitterAccounts count]」が「0」となり、「[self alertAccountProblem]」が呼ばれます。このメソッドは後ほど実装しますが、ユーザーをアプリからiOSの設定画面に誘導するものとなっています。

次に、JSONを取り扱う際に、今回はNSJSONSerializationクラスを用いています。これはiOSに含まれる、比較的便利なJSON解析用のクラスとなっています。このクラスを用いることで、文字列としてのJSONメッセージを解析し、配列に含まれる20個のTweetを「JSONオブジェクト」としてNSArray型の配列に取り込むことができます。このJSONオブジェクトは、JSON形式のデータを取り扱うデータ型の一種と考えて下さい。

最後に、Tweetを取得する際に必要な複雑なユーザー認証やHTTP通信はすべてTwitterフレームワーク側で取り扱われるため、我々は特に何も心配することはありません。

Twitterアカウント設定画面へのリダイレクト

先ほども述べたとおり、このアプリはiOS側にTwitterのアカウントが登録されていることを前提としています。ここでは、アカウントが1つも登録されていない時、ユーザーを設定画面へ誘導するためのメソッドを記述します。

以下の通り、View Controllerに、以下の通りメソッドを記述します。

ViewController.m
//アカウント情報を設定画面で編集するかを確認するalert View表示

-(void)alertAccountProblem {

    // メインスレッドで表示させる

    dispatch_async(dispatch_get_main_queue(), ^{

        //メッセージを表示

        UIAlertView *alert = [[UIAlertView alloc

            initWithTitle:@"Twitterアカウント" 

            message:@"アカウントに問題があります。今すぐ「設定」でアカウント情報を確認してください" 

            delegate:self 

            cancelButtonTitle:nil 

            otherButtonTitles:@"はい"

            nil

        ];

        [alert show];

    });

}


ここでは、Twitterアカウントの設定に問題があった場合に表示されるAlert Viewを設定しています。ただしそのまま出力するとエラーが発生しますので、 dispatch_asyncという仕組みを使い、表示させるようにします。


Table Viewの設定

次に、Table Viewの設定を行います。まずは、View Controllerのインターフェースファイル上でプロトコルの設定を行います。ViewController.hを以下の通り編集してください。

ViewController.h
 @interface ViewController : UIViewController<UITableViewDelegateUITableViewDataSource>

次に、Table Viewが表示されるために必要とする3つのメソッドを実装していきます。

ViewController.m

//Table Viewのセクション数を指定

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    return 1;

}


//Table Viewのセルの数を指定

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return [tweets count];

}


//各セルにタイトルをセット

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    //セルのスタイルを標準のものに指定

    static NSString *CellIdentifier = @"TweetCell";

    UITableViewCell *cell =  [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    

    //カスタムセル上のラベル

    UILabel *tweetLabel = (UILabel*)[cell viewWithTag:1];

    UILabel *userLabel = (UILabel*)[cell viewWithTag:2];

    

    //セルに表示するtweetJSONを解析し、NSDictionary

    NSDictionary *tweetMessage = [tweets objectAtIndex:[indexPath row]];

    

    //ユーザ情報を格納するJSONを解析し、NSDictionary

    NSDictionary *userInfo = [tweetMessage objectForKey:@"user"];

    

    //セルにTweetの内容とユーザー名を表示

    tweetLabel.text = [tweetMessage objectForKey:@"text"];

    userLabel.text = [userInfo objectForKey:@"screen_name"];

        

    return cell;

} 


まず、最初に1つ目のメソッドでテーブルのセクションの数を設定し、2つ目のメソッドでセルの個数を設定します。これらを元に、セルが準備されるので、3つめのメソッドでセルの内容を埋めます。

「RSSリーダー」でも扱ったように、3つ目のメソッドは各セルの内容を埋めるためのものです。基本的には、セルのIdentifierを指定し、2つラベルのTag番号を指定した上で、それらに文字列を流し込みます。

ここで「RSSリーダーの時と大きく異なるのは、JSONの中身をNSDictionary型のインスタンスに落とし込んでいることです。前述したように、JSONファイルは「名前(キー)」と「値」の組み合わせで構成されています。このような構成のデータを取り扱う場合で、NSDictionaryのような「連想配列」を用いることで、非常に効率良くデータを扱うことができます。

通常の配列であるNSArrayの場合、先頭の項目を0番目とし、各項目にインデックス番号が付けられています。例えば全部で10個の項目があった場合、最初の項目のインデックス番号は「0」、最後の項目のインデックス番号は「9」となります。一方、NSDictionaryに代表される連想配列はJSON同様、「名前(キー0)でデータを管理します。そのため、各TweetをまとめたJSONオブジェクトをそのまま、NSDictionary型のインスタンスに流しこむことができます。

実際に、NSDictionaryに含まれる項目を参照する手順を見て行きましょう。例として、「tweetMessage」という、1つのつぶやきに関するあらゆる情報(ユーザーや日時、場所、Tweet文などをひとまとめにした連想配列(NSDictionary)から、Tweetの内容(Tweet文)を抽出する例を考えます。Tweetに関する情報をまとめたNSDictionaryでは、「text」というキーに紐付く形で、Tweet文が保存されています。そこで、以下の例では、「tweetMessage」という連想配列から「text」というキーがついたものを抽出し、「tweetText」という文字列代入しています。

//NSDictionaryからTweetの内容を文字列として読み出し

NSString *tweetText = [tweetMessage objectForKey:@"text"];


Twitter APIが提供する1つのTweetごとのJSONオブジェクトは、以下のような構成になっています。

{

  "text": "Walking the DOM like Huggybear.",

  "user": {

      "screen_name": "kplawver"

    …その他ユーザー情報…

  },

  …その他Tweetに関する情報…

}


基本的には、ユーザー情報を除く全ての情報は同じ階層にあります。ユーザー情報のみ、「user」という「キー」の「値」として、ユーザー情報を含む別のJSONオブジェクトが設定されています。

今回は、まずTweetを表すJSONオブジェクトを「tweetMessage」というNSDictionary型のインスタンスに流し込んでいます。その上で、「user」というキーの値を「userInfo」という別のNSDictionary型のインスタンスに流し込んでいます。その後、それらから「text」というキーと「screen_name」というキーの値を、それぞれユーザー名と本文を表示するラベルのテキストとして設定しています。

今回はTwitter APIに焦点を当てていますが、Facebookと連携するサービスを作る上で利用するGraph APIやGoogleの提供する各種APIもJSONを用いてデータの受け渡しを行なっています。様々な値に「キー」という文字列をつけて管理する概念はよく使うと思うので、是非いろいろ調べてみてください。また、前述したように、JSONと連想配列は非常に親和性が高いので、セットで使い方を覚えるといいでしょう。

Table Viewのセルがクリックされた場合の処理

Tweetの本文をラベルに表示する際、本文が全角32文字を超える場合、以下のように、省略表示されます。



そこで、セルがクリックされた場合、Tweetの全文をAlert Viewとして表示するようにします。



それでは、実際にコードを記述します。

ViewController.m
//リスト中のTweetが選択された時の処理

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    

    //セルにされているtweetJSONを解析し、NSDictionary

    NSDictionary *tweetMessage = [tweets objectAtIndex:[indexPath row]];

    

    //ユーザ情報を格納するJSONを解析し、NSDictionary

    NSDictionary *userInfo = [tweetMessage objectForKey:@"user"];


    //メッセージを表示

    UIAlertView *alert = [[UIAlertView allocinit];

    alert.title = [userInfo objectForKey:@"screen_name"];

    alert.message = [tweetMessage objectForKey:@"text"];

    alert.delegate = self;

    [alert addButtonWithTitle:@"OK"];

    [alert show];

}


基本的には、セルのラベルにユーザー名とTweet本文を表示させる処理と流れは同様です。JSONオブジェクトをNSDictionary型のインスタンスに流しこみ、該当するキーの値をAlert Viewのタイトルと本文に設定しています。

Table Viewの表示を更新

TwitterフレームワークはTweet APIを用いてJSON形式のメッセージを受信する際、「RSSリーダー」同様、バックグランドでデータのダウンロードを行なっています。そこで、バックグランドでのデータ受信処理が完了した際、Table Viewの表示をフロント側で更新するメソッドを記述します。

FirstViewController.m
//フロント側でテーブルを更新

- (void) refreshTableOnFront {

    [self performSelectorOnMainThread:@selector(refreshTable) withObject:self waitUntilDone:TRUE];

}


//テーブルの内容をセット

- (void)refreshTable {

    //ステータスバーのActivity Indicatorを停止

    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

    //最新の内容にテーブルをセット

    [table reloadData];

}


Tweetの投稿画面の呼び出し

ここまでで、Tweetの表示を行う処理の記述が完了しましたが、Twitterクライアントとして成り立つためには、Tweet一覧を見るだけでなく、Tweetを投稿する機能も必要になります。
幸いにも、TwitterフレームワークはアプリからTweetを投稿するための仕組みを用意しています。自らText Fieldや投稿ボタンを設置して、入力した内容を投稿する仕組みを独自に作ってもいいのですが、今回はTwitterフレームワークが提供するTweet作成画面を呼び出すことにします。



「Tweet投稿」ボタンによって上記画面が呼び出されるよう、以下のとおり、IBAction型のメソッドを記述して下さい。

ViewController.m
//Tweet作成画面を起動

- (IBAction)sendEasyTweet:(id)sender {

   

    //SLComposeViewControllerのインスタンス生成

    SLComposeViewController *tweetViewController = 

        [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];


    //Tweet投稿完了時・キャンセル時に呼ばれる処理

    [tweetViewController setCompletionHandler:^(SLComposeViewControllerResult result) {

         switch (result) {

             case SLComposeViewControllerResultCancelled:

                 NSLog(@"キャンセル");

                 break;

             case SLComposeViewControllerResultDone:

                 NSLog(@"Tweet投稿成功");

                 break;

             default:

                 break;

         }

         //Tweet画面を閉じる

         [self dismissViewControllerAnimated:YES  completion:nil];

     }];

    

    //Tweet画面を起動

    [self presentViewController:tweetViewController animated:YES completion:nil];

}


Tweet一覧を再読み込みとView Controllerの初期処理

ここでは「更新」ボタンが押された際に呼ばれる、Tweet一覧を再読み込みするIBAction型のメソッドを実装します。以下のとおりViewController.mに記述して下さい。

ViewController.m
-(IBAction)refreshTimeline:(id)sender {

    [self getTimeline];

}


次に、View Controllerの初期処理を実装します。以下の通り「viewDidLoad」メソッドを編集します。

- (void)viewDidLoad {

    [super viewDidLoad];    

    [self getTimeline];

}


UI画面とコードの関連付け

ここまでで、基本的にコードの記述は全て完了となります。そこで、これまでに設置したUI画面上の部品とコード上の処理を関連付けます。

まずは、「更新」ボタンと「Tweet投稿」ボタンを、それぞれView Controllerの「refreshTimeline」と「sendEasyTweet」と関連付けます。その際、Document Outlineを使うと良いでしょう。Document Outline(下記画面の左側のリスト)が出ていない場合は、Interface Builderの画面左下にあるボタンをクリックして下さい。





次に、Table Viewの「delegate」と「dataSource」をView Controllerと関連付けます。



その後、Table ViewそのものをView Controllerの「table」と関連付けます。


その後、Table ViewそのものをView Controllerの「table」と関連付けます。


ビルドと動作試験

これにて、すべての作業は完了となります。編集内容を全て保存し、ビルドを行なってください。このテキストの内容をすべて正しくやった場合、特に問題なくアプリが動作するはずです。
Tweetが呼び込まれること、Tweetが投稿できること、そして、Twitterアカウントにエラーがある場合はTwitterの設定画面にリダイレクトされることを確認して下さい。


まとめ

第10講では、Twitterのような外部サービスとアプリを連携させる手法を取り扱いました。その中でも、今回はiOS SDK 5に含まれるTwitter フレームワークを利用し、独自のTwitterクライアントを作成しました。また、その過程で、JSON形式のメッセージやTwitter APIの仕組みも解説しました。

今回は機能をタイムラインの一覧を取得とTweetを投稿に絞り、非常にシンプルなTwitterクライアントを作成しました。しかし、Twitter APIは非常に多くの機能を提供しているので、余力のある方はぜひそれらを調べ、今回のアプリにTweet検索機能や、フォロー中ユーザーやフォロワーの一覧表示機能を実装してみて下さい。

次回は、QRコードを読み込む手法やアプリとアドレス帳と連携させる手法を取り扱うアプリを作成します。
Comments