flickr + WordPressでプライベートな写真を身内限定で公開する

ことの発端は iCloud です。

MobileMeがiCloudに移行すると、ギャラリーが無くなってしまうというのです。それは困った。

子供が産まれてから、写真や映像は全てMobileMeギャラリーにパスワード付で公開して、実家のみなさんにお見せする、というのが今までのスタイルだったからです。

それに変わる方法を見つけないといけない。それがここ数ヶ月の悩みの一つでした。

大手の写真共有サービスといえばご存知 flickr や Picasa。仲間内ということであれば最近はやりのfacebookでもいいかもしれません。でも、どれもがMobileMeに慣れた身としては使い勝手が微妙なのです。

共有する相手もそのサービスのアカウントを持っていないといけない

たいてい、写真をプライベートに共有しようとすると、その共有先の相手のアカウントと紐づける必要がでてきます。それは面倒。だって、別に使いもしないであろう共有サービスのアカウントをとってもらわないといけないわけですから。その上で、そのサービスの使い方サポートもしてあげないといけないかもしれないのです。うん、面倒。

都度公開URLを生成しないといけない

アカウントが不要な場合でも、たいていは類推できないような長いURLを用いて、そのプライベート性を担保していることが多いです。だとすると、一つのアルバム(たいていはイベントごとに作ります)を公開するたびに、そのURLを取得し、メールなりで送る必要がでてきます。これも面倒。

理想はやっぱりMobileMe的な操作感

MobileMeではいつもこうでした。

  1. iPhotoなりApertureなりに写真を取り込む
  2. イベントごとにアルバム作って整理
  3. アルバムをまるごと送信←ここで任意のパスワード(といってもいつも同じもの)を付与
  4. あとはなにもしない(「写真置いたからみてね」っていうだけでOK。連絡してなくても適当な時に見にいってもらえればそれでOK)

そこまでガチガチにプライベート性にこだわるわけではないのです。でも、フルオープンなのも困ります。だって、家族の写真なのですから。

そんなこんなで色々と考えていて、思いついたのがこれ。

WordPressのプラグインでなんとかならないか?

そうそう、せっかくサーバがあるわけなので、自前でWordpressサイトを立ち上げて、そのプラグインでうまくプライベートな写真を表示できるようにすればよいのでないかと。もちろんWPにこだわるわけではないですが、そのプラグインの豊富さからいえば、きっと自分に合ったものが見つかるはず、と思ったわけです。(要するに、全体にわたってそんなにこだわりはないのです。とにかく楽したい)

共有サービスとの連携も考えつつ、色々なプラグインを探してみました。で、その結果。

flickr + WordPressでいけそうだ!

共有サービスといえば上述のように flickr か picasa の2択だと思ってました。どちらも無料・有料のサービスですね。picasaは先日Google+がはじまったことでほぼ無料になってしまいましたが。

で、なんで flickr にしたかというと。まずはMacとの相性。iPhotoやApertureに標準でプラグインが組み込まれていること。これ結構大事。

それとAPIの相性。

サービス側で非公開にしている写真にアクセスするっていうことは、そのプラグインに閲覧権限を与える必要があります。つまり、プラグイン自体が普通の外部アプリのように振る舞えなくてはなりません。で、何が必要になるかっていうと、そのアプリとしての登録。flickrなりgoogleなりのAPIを使うアプリですよ、っていうのを登録してキーをもらわなければなりません。で、googleのは個人的に登録が面倒だったんですよね。flickrはなれているっていうのもあって簡単にできたし。プラグインを選ぶ段階で楽にできるっていうのは結構アドバンテージ高かったです。

ちなみに、flickrはPictShareのテストでどうしてもProアカウントが必要になって、Proアカウントにアップグレードしてしまってたっていうのもありましたね。

まあ、結局のところ、やりたいことができるプラグインが存在しないとなんの意味もないのですけれど、そういう基準でもっていろいろと探してみました。

最終的に見つけたプラグインはこれ。

Flickr Gallery

ちょっと古いんですが、最新のWPでも一応動いています。API KeyやらユーザIDやらを入力して、コードを任意のページに貼り付けるだけ。全てのフォトセットがもれなく表示されてしまうものの、そもそも共有用に使うと思えばそれも全然問題なし。ただ、1ページに全部表示されてしまうので、フォトセットが多くなった時が不安ではあるんですけれど、、、その時は自分でなんとかしますかねえ。

ちなみにパスワード保護として、最初は単純にBasic認証を考えていたんですが、これもまあ単純なプラグインがあったので、こちらを使うようにしました。

これらを取り込んだWordpressサイトを別途立ち上げて、いまのところは順調に実家のみなさんに写真を共有できています。

まあ、ざっくりこんなサイトです。

3つ目のフォトセットが開かれている状態ですね。

なんか、ほかに便利そうな方法があったら教えてくださいな。あ、でももうflickrをじゃんじゃん使っているのでflickr限定でお願いします。

iPhoneとTwitter OAuth認証の流れについて

twitterヘの認証方式は2つありまして、1つはお馴染みBasic認証。もう1つがOAuthです。で、なにやら、今後はOAuthしか受け付けなくなるとかいう話があって、ちょっと盛り上がっているtwitterクライアント界隈。

OAuthの細かい話はさておき、twitterのOAuth認証(access_token取得)の手順には2通りがあります。(太字はiPhone上での主な挙動)

サーバ型

  1. アプリごとの key から request_token 取得
  2. request_token を用いて twitter のサイトを表示
    → MobileSafari起動
  3. ユーザにログインしてもらう
  4. 設定していた callback URL が呼び出される
    → サーバ側で元アプリの URL scheme にリダイレクトし、元アプリを起動
  5. callback に渡された oauth_token から access_token を取得
    → アプリ起動時に渡された URL から access_token を取得

クライアントアプリ型

  1. アプリごとの key から request_token 取得
  2. request_token を用いて twitter のサイトを表示
    → 内蔵ブラウザで表示
  3. ユーザにログインしてもらう
  4. サイトに表示されたPINをアプリに入力してもらう
    → ユーザがブラウザ外のフィールドに別途入力
  5. 入力された PIN から access_token を取得

まあ、セキュリティ云々の話は別として、どっちもどっちだと思うわけです。サーバ型ではアプリをいったん離れなければなりませんし、クライアントではPINを入力するという手間がかかります。

じゃあ、アプリを離れることなしに、サーバ型の方式は使えないのかと思って試してみました。

やってみたこと

UIWebView の delegate でアクセス予定の URL を取得できます。ここで、指定していた callback URL にアクセスしようとしていたら、そこから oauth_token パラメータを取り出せるのではないかと考えました。

結果

予想通り、UIWebView の delegate で (4) の callback 呼び出しをとらえて、そこから oauth_token を取得することができました。これだと操作がアプリ内蔵の UIWebView だけでとじているので、アプリの切替もPINの入力も要りません。極端な話、callback URL 先の実体すら不要です(存在しないURLを指定していても大丈夫のようです←実際にアクセスする前に request を止めるので当然といえば当然ですが)

delegate 内はこんな感じで。

- (BOOL)webView:(UIWebView *)webView
    shouldStartLoadWithRequest:(NSURLRequest *)request
    navigationType:(UIWebViewNavigationType)navigationType {
    if ([[request.URL host] isEqualToString:@"callback.example.com"]) {
        NSString* query = [request.URL query];
        NSArray* arr = [query componentsSeparatedByString:@"="];
        if ([arr count] > 1 && 
            [[arr objectAtIndex:0] isEqualToString:@"oauth_token"]) {
            NSString* token = [arr objectAtIndex:1];
            // do something
        }
        return NO;
    }
    return YES;
}

OAuthの運用上、あるいはセキュリティ上の問題があるかもしれませんが、それらをさておいたとして純粋にユーザ視点にたてば、これが一番スマートなのではないでしょうか、と。

あとは、twitterのログインページがiPhoneに最適化されれば問題ないんですけれど・・・

***一応、手元で開発中にアプリでは問題なく動いているんですが、なんかおかしかったら教えてくださいませ。

iPhoneアプリ内でYouTube動画を再生する

たまには開発の小ネタでも。

ご存知のようにiPhoneでFlashは再生できません。なので、基本Flashベースで動いているYouTubeの動画なんかも再生できません。(もちろん、標準のYouTubeアプリは別ですが)

動画再生専門のアプリならともかく、ちょっとしたYouTube動画を再生したいと思った場合には、標準のYouTubeアプリをURLスキームで起動するのが手っ取り早いわけですが、それだと自分のアプリに戻ってこれなくなります。

そこで、YouTube動画をアプリ内で再生する方法。

YouTubeはFlashベースではありますが、MP4ファイルが取り出せることもよく知られている事実です。もちろん簡単には取り出せないのですが、

この辺りを参考にしますと、get_video_info.php で取得した token を用いて fmt=18 を指定すればmp4で取得できそうです。

余談ながら、最初はサーバでこのtokenを取得してアプリからの要求をリダイレクトさせようと思ったのですが、tokenはアクセス元によって異なるようなので、DL元(今回の場合はiPhoneアプリ)でtokenを取得しないと行けないようです。

というわけで、NSURLConnection あたりを用いて token を取得し、それをそのまま MPMoviePlayerController に渡せば無事に YouTube の動画再生ができました。(コンソールには Warning: MPMoviePlayerController may not support file of type php のようにPHPファイルは再生できないといった警告がでますが、YouTube側のリダイレクトの話なので特に問題なさそうです)

任意の video_id を渡して MPMoviePlayerController で再生するサンプルコードを GitHub においてますので、参考にしてください。