Hatena::ブログ(Diary)

maneman8000の日記

2011-03-29

Objective-CによるOAuth2のサンプルを作ってみた

ここ最近iPhone(iPad)アプリ開発に興味を持ってます。

ちょっとPicasaの写真を表示してみたいなと思ったところで、最近対応されたGoogleのOAuth2のサンプルのようなものがあまりなさそうなので作ってみました。といってもOAuth2自体は1に比べてシンプルなプロトコルになっているので必要性は薄いかもしれませんが、ひとつの実装例として見ていただけると幸いです。

さてGoogleのOAuth2ですが、まず準備としてこちらのサイト(Error 404 (Not Found)!!1)の説明に従い、自分のアプリの登録を行います。この操作により自分のアカウントに関連付けられたClient IDとClient Secretが発行されます。また、ここで、redirect URIにローカルアプリ用の

urn:ietf:wg:oauth:2.0:oob

という値を登録します。

アプリからの認証の流れは以下のようになります。

  1. Client ID、サービスのスコープ(一覧)などを含めたURLのページを開き、ユーザにアクセス許可を求める
  2. ユーザにOKされたらAuthorization Codeが発行されるので、そのページのタイトルなどからAuthorization Codeを取得する
  3. 上で得られたAuthorization Code、Client ID/Secretなどを用いてGoogleサーバAccess Tokenのリクエストを送信する
  4. 上で得られたAccess Tokenを用いて各サービスにアクセスする

で、今回作成したサンプルは以下になります。私はiPadしか持っていないためiPadアプリケーションとしてつくっております。

GitHub - maneman8000/SampleOAuth: iPad sample application of google OAuth2.0

Client IDとClient Secretは入れていないので、GitHubからソースを落としたら SampleOAuthフォルダ内に OAuth2GoogleClient.h というファイルを作成し、以下のように自分のClient IDとClient Secretを定義していただく必要があります。

#define GOOGLE_OAUTH2_CLIENT_ID @"ここに Client ID を貼り付ける"
#define GOOGLE_OAUTH2_CLIENT_SECRET @"ここに Client Secret を貼り付ける"

ビルドして実行していただくとユーザに許可を求めるページが表示されます。アカウントを入力して許可すると、自分のPicasaのアルバムのXMLがそのままTextViewに表示されます。

なお、現状ではRefresh Tokenによる権限の更新は実装していません。おいおい追加する予定です。

2011-03-18

Objective-CのMessage Forwarding

Objective-Cではオブジェクトに存在しないメッセージを送ると例外が発生します。しかし、Message Forwardingと呼ばれる機能を用いるとそのような場合に例外を出すことなくメッセージを処理することが出来るようになります。これは、PerlのAUTOLOADと同じと考えて良いようです。

で、このMessage Forwardingなんですが、恐らくフレームワークライブラリなどを設計する場合には強力な助けとなる機能のようですが、アプリケーションを作る場合にはあまり使う場面は少なそうです。Appleドキュメントでは継承の代わりに使う例が紹介されてますが、「Modern Perl」のAUTOLOADのサンプルで出ていた「メソッド呼び出しを記録するProxyクラス」という例も面白いものなので、これをObjective-Cで書き直したものとして紹介したいと思います。

このProxyクラスの名称はLogProxyとします。LogProxyは以下のように使うことを想定してます。

// Testクラスのメソッド呼び出しを記録する
id test = [[LogProxy alloc] initWithTarget:[[Test alloc] init]];
[test someMethod];   // ログに記録される

ではLogProxyの実装を見てみましょう。まずインターフェース部分。

@interface LogProxy : NSObject {
    id proxied;
}
- (id)initWithTarget:(id)target;
- (void)dealloc;

@end

Message Forwardingの転送先としてproxiedという変数を保持するようにします。また、proxiedはコンストラクタで与えるようにしてます。

次に実装部分です。Message Forwardingを行うためには、forwardInvocation:とmethodSignatureForSelector:という2つのメソッドを実装する必要があります。forwardInvocation:は存在しないメッセージ呼び出しがあったときに代わりに呼ばれるメソッドで、引数としてNSInvocationのオブジェクトを取り、そこから呼び出されたときのセレクタの情報などを取得することができます。また、methodSignatureForSelector:はメソッドシグネチャを返すもののようです。あまりこちらは理解できてないのですが、親クラスのものか転送先オブジェクトのそれを返すことでよいようです。実装のコードは次のようになります。

@implementation LogProxy

- (id)initWithTarget:(id)target {
    if ((self = [super init]) != nil) {
        proxied = target;
    }
    return self;
}

- (void)dealloc {
    [proxied release];
    [super dealloc];
}

// 存在しないメッセージが送られたときに呼ばれる
- (void)forwardInvocation:(NSInvocation *)anInvocation {
    // 関数呼び出しのログを記録する
    NSLog(@"Called [%@]", NSStringFromSelector([anInvocation selector]));
    // メッセージを転送
    [anInvocation invokeWithTarget:proxied];
}

// こちらは決まりきったコード(?)
- (NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector {
    if ([super respondsToSelector:aSelector])
        return [super methodSignatureForSelector:aSelector];
    return [proxied methodSignatureForSelector:aSelector];
}

@end

以上。基本的には「Modern Perl」に出ていたもののマネですが、転送をプロクシ的に使うというのは何か別の応用も考えられるかもしれません。

2011-03-06

「Modern Perl」の電子版があった

読み終わりました。自分はあまりモダンPerlてのを知らなかったので参考になることばかりでした。

ところで、著者のブログを眺めていたら、驚いたことに電子版を無料配布されておりました。epub版もあるらしいです。変換すればkindleでも見れるかな。

Share the Modern Perl ePub - Modern Perl Programming

2011-02-20

「Modern Perl」メモ2

Modern Perl」読書メモ2。75ページぐらいまで。

ハッシュのスライシングがらみの内容は知らないことが多くためになりました。

2011-02-18

「Modern Perl」メモ

Modern Perl」読書メモ。「モダンPerl入門」も実はまだ読んでなくてそちらも読みたいのだけど、洋書が安いのでついこちらを買ってしまった。50ページぐらいまで読んだところで、自分的に有用だった事柄をメモ。

  • Windowsではstrawberry perlを使う
  • Modern::Perl
  • perldocで調べるのが早い
  • ハッシュのスライシング(@hash{@key} = @val みたいなやつ)
  • $_にmyをつけるとスコープ限定で使える
  • Regexp::Common
  • リスト戻り値の個数を数えるイディオム(my $count=()=get_some_list();)
  • given/when構文
  • Scalar::Util

我流だった部分を直せるのでいい感じ。特に今までActivePerlを使っていたのはイタかった。Windowsでも普通にcpanて使えたんですね・・・。

Connection: close