iPhone用Twitterアプリのつくりかた
Twitterと連携したアプリを作成しているところなのですが、何とか自由にTLを取得したりつぶやきをポストできるようになったので、備忘録がてらその方法を紹介します。「iPhoneアプリ作ってみたいけど、ネタがない!」なんて方には参考になるかもしれません。
Twitterの認証方法
現在Twitter APIを利用するための認証方法としては、以下の2つが考えられます。
-
- OAuth
- xAuth
Basic認証が8月下旬に終了とのことで、OAuthを説明したエントリなんかがよくありますね。難しい話はOAuth.netの方に任せますが、基本的にこれからは、TwitterクライアントではOAuthを使用していくことになります。ですがこのOAuth、作成するクライアントによっては面倒な作業が必要になってきます。
OAuthではクライアント固有の、Consumer KeyとConsumer Secret Keyを使用します。またこれらのキーからユーザ自身がTwitterアカウント固有の、Access TokenとAccess Secret Tokenを取得し、それをもってユーザ認証を行ないます。よくTwitterを使用したWebアプリケーションの利用登録時、Twitter公式に飛ばされて「◯◯というアプリとあなたのTwitterアカウントを連携しますか?」といった申請を行ったことがある方も多いかと思います。これがまだWebアプリケーションなら、別ウィンドウでTwitter公式に飛んで、申請されたらWebアプリケーションのトップページにリダイレクトするだけで済みます。しかし作成しているTwitterクライアントがデスクトップアプリケーションなら、ユーザーにわざわざブラウザで作業してもらったり、クライアントに簡易ブラウザを実装したりと話が複雑になってきます。
そこで最近OAuthと並んで話題になっているのがxAuthです。Twitter公式側に自分の作っているクライアントを申請すれば、Consumer KeyとConsumer Secret Keyからプログラム側でAccess TokenとAccess Secret Tokenを取得できるのです。クライアント側で取得したTokenを保存しておけば、従来のBasic認証とほぼ変わらないシステムを作れるのです*1。
xAuthでもAccess TokenとAccess Secret Tokenを使うことには変わりないので、今回はOAuthを使用したTwitter APIの利用方法を紹介します。
キー・トークンの取得
いきなり端折ってしまいますが、Consumer KeyやConsumer Secret Keyの取得は以下のTwitter公式ページより行ってください。作成しようと思っているクライアントの基本情報を登録するだけです。投稿機能もクライアントに入れるなら、Default Access typeはRead & Writeにしてください。
次にAccess TokenとAccess Secret Tokenを取得するにはid:shibasonさんの以下のエントリが参考になります。twitter-oauth.rbというRubyスクリプトの、Consumer Key等に関する部分を書き換えてください。
いよいよXcodeを使ってコーディング
では早速取得したキー・トークンを使って簡単なアプリを作ってみましょう。
まずXcodeを起動し、新規プロジェクトを作成します。とりあえず「View-based Application」にします。
Interface Builderは使用しない系男子
好みは分かれるかもしれませんが、僕はInteface Builderはあまり使用しないので、それらに関する項目を消します。まずはmain.mを以下のように修正します。
#import <UIKit/UIKit.h> int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int retVal = UIApplicationMain(argc, argv, nil, @"MyTwitterAppDelegate"); [pool release]; return retVal; }
次に、プロジェクト内のMainWindow.xibを削除します。
最後にMyTwitter-Info.plistを開き、「Main nib file base name」というキーを選択しDeleteキーで削除します。
OAuthライブラリを導入
自力でOAuth認証を実装する気はないのでライブラリを使いましょう。調べてみるとOAConsumerというライブラリが広く使われているそうです。しかしそのままiPhoneアプリに組み込むには少々厄介なので、以下のライブラリを使わせてもらいます。
jdg's oauthconsumer at master - GitHub
ページ右上部分の「Download Source」というリンクからソースファイルをDLしてください*2。DLしたzipファイル、もしくはtarballを展開したら、全てのファイルをプロジェクトに追加します。
READMEにある通り、Security.frameworkとlibxml2.dylibをプロジェクトのフレームワークに追加します。追加すると以下のようなフレームワークが並びます。
最後にヘッダ検索パスの設定を行ないます。以下の画像のようにファイルツリー一番上の「MyTwitter」というプロジェクトファイルを選択し、メニュー一番右の「情報」という青いアイコンをクリックします。
以下のような設定画面が出てきますので、「ヘッダ検索パス」という項目を探してください。
「$SDKROOT/usr/include/libxml2」というパスを追加します。「再帰的」にはチェックを忘れずに!
OAuthConsumerを少々修正
ここまで進めて、とりあえずOAuthConsumerを使用することはできるのですが、コンパイル時に警告が出てしまうので少しソースを修正します。ちょっと自信ないというか無理矢理な修正ですが、おそらく動作に問題はありません。
まずOACall.mでは、140行目辺りの以下のifブロックをコメントアウトします。
// attachFileWithName:filename:data:っていうメソッドがないみたいです。 // if (self.files) { // for (NSString *key in self.files) { // [request attachFileWithName:@"file" filename:NSLocalizedString(@"Photo.jpg", @"") data:[self.files objectForKey:key]]; // } // }
OAToken.mではattributesアクセサメソッドに関する部分を、3箇所修正します。
... // self.attributes = theAttributes; self.attributes = (NSMutableDictionary *)theAttributes; ... // - (void)setAttributes:(NSDictionary *)theAttributes { - (void)setAttributes:(NSMutableDictionary *)theAttributes { ... // self.attributes = [[self class] attributesWithString:theAttributes]; self.attributes = (NSMutableDictionary *)[[self class] attributesWithString:theAttributes]; ...
TLを取得してみる
それではタイムラインを取得してみましょう。まずMyTwitterAppDelegate.mのapplication:didFinishLauchingWithOptions:メソッドを以下のように記述します。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { viewController = [[MyTwitterViewController alloc] init]; [viewController getTimeline]; [window addSubview:viewController.view]; [window makeKeyAndVisible]; return YES; }
ビューコントローラ側でTL取得メソッドを書きたいと思います。MyTwitterViewController.hのインターフェイス部では、
#import <UIKit/UIKit.h> @interface MyTwitterViewController : UIViewController { } - (void)getTimeline; @end
MyTwitterViewController.mではヘッダファイルをインポートし、3つのメソッドを実装します。
#import "OAuthConsumer.h" ... - (void)getTimeline { NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/home_timeline.xml"]; OAConsumer *consumer = [[[OAConsumer alloc] initWithKey:@"CONSUMER_KEY" secret:@"CONSUMER_SECRET_KEY"] autorelease]; OAToken *token = [[[OAToken alloc] initWithKey:@"ACCESS_TOKEN" secret:@"ACCESS_SECRET_TOKEN"] autorelease]; OAMutableURLRequest *request = [[[OAMutableURLRequest alloc] initWithURL:url consumer:consumer token:token realm:nil signatureProvider:nil] autorelease]; [request setHTTPMethod:@"GET"]; OADataFetcher *fetcher = [[[OADataFetcher alloc] init] autorelease]; [fetcher fetchDataWithRequest:request delegate:self didFinishSelector:@selector(ticket:didFinishWithData:) didFailSelector:@selector(ticket:didFailWithError:)]; } - (void)ticket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data { NSString *timeline = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; NSLog(@"%@", timeline); } - (void)ticket:(OAServiceTicket *)ticket didFailWithError:(NSError *)error { NSLog(@"Error"); }
CONSUMER_KEYやACCESS_TOKENといった部分は先程自分で取得したものに修正してください。コードの大部分はid:sugyanさんの以下のエントリを参考にしました。