5分で使い始めるInstagramAPI


最近 version2.0 になってますます最高です!なインスタグラム。
今になってAPI使ってみたので、とりあえずどんな感じかサクッと使ってみたい方の為にエントリます。


※インスタグラムのユーザー登録してる事前提です。ここではmacで作業してます。



STEP1. クライアント登録


http://instagram.com/developer/
こちらのデベロッパページに行きます。

こんな感じの画面です。


このページ中の、Register your application をクリックすると
http://instagram.com/developer/manage/
こちらのクライアント登録ページへ遷移します。


Register a New Client をクリックして、クライアント登録を行います。

全ての項目を埋めてください。
内容は適当で良いのですが、Website と OAuth redirect_uri はアクセスするサイトのURLを入力してください。
ここではとりあえずローカルの開発環境のURLを入れてます。


登録すると、

こんな感じで、CLIENT ID と CLIENT SECRET が割り当てられます。
この2つのトークンは後で使います。


ここまでの処理で、ポピュラー(人気写真)取得APIなどの認証がいらないAPIは使用できます。

https://api.instagram.com/v1/media/popular?client_id=取得したCLIENT ID

へブラウザからアクセスするとデータが取得できるのが分かると思います。


自分の写真を取得したい!等といった場合のAPIを実行するには認証が必要で、アクセストークンを取得する必要があるので以下の処理を行ってください。



STEP2. code取得


次に、アクセストークンを入手する為に必要な、codeを取得します。

https://api.instagram.com/oauth/authorize/?client_id=取得したCLIENT ID&redirect_uri=登録したOAuth redirect_uri&response_type=code

上のURLに自分の値を当てはめて、ブラウザからアクセスします。


インスタグラムのユーザーID, パスワードを入力する画面になるので、入力すると、以下の画面に遷移します。

Yes を選択すると、先ほど指定した OAuth redirect_uri に、code付きでリダイレクトされます。



このcodeを使用しますので、コピペしておきます。



STEP3. access_token取得


最後に認証用の access_token を取得します。


ターミナルを立ち上げて、以下のコマンドを実行します。

curl \
-F 'client_id=取得したCLIENT ID' \
-F 'client_secret=取得したCLIENT SECRET' \
-F 'grant_type=authorization_code' \
-F 'redirect_uri=先ほど入力したOAuth redirect_uri' \
-F 'code=取得したcode' \
https://api.instagram.com/oauth/access_token


こんな感じで実行します。



こんな感じで結果が取得できます。
access_token をメモりましょう。



STEP4. 使ってみる

https://api.instagram.com/v1/users/search?q=自分のユーザー名&access_token=取得したaccess_token

へブラウザからアクセスすると、自分の情報を取得できます。
うまく取れたら、id という値があるのでメモしときます。
ユーザーに関するAPIはこのidを使います。

https://api.instagram.com/v1/users/取得したid/media/recent?access_token=取得したaccess_token

へブラウザからアクセスすると、自分の最近の写真に関するデータが取得できます。




後は各種APIJavascriptから叩くなりなんなりしてマッシュアップしてみてください。Enjoy!

UINavigationBarのbackボタンが表示されなくてお嘆きのあなたへ

UINavigationBar で pushViewController メソッドで次の画面へ遷移したのに、左上の戻るボタンが表示されなくてお嘆きになるケースってあると思います。


たいていの場合、タイトルに文字列が無い場合にこの状況に陥っていると考えられるのですが、例えばNavigationBarにカスタム画像等を使用している場合等はタイトル表示したくない。




その場合以下の方法です。

UIBarButtonItem *backButton = [[[UIBarButtonItem alloc] init] autorelease];
backButton.title = @"戻る";
self.navigationItem.backBarButtonItem = backButton;

InterfaceBuilder での設定は、Back Button プロパティに入力するだけ。

※Xcode4です


はい出た。


意外と気づかずにハマる事が多いと思います。
以上、MacのキャプチャツールSkitchが無料になっていたので使ってみたくて書きました。

Interface Builder でxibファイル開けなくなった

作業してて、マシン再起動した後で、MainWindow.xib を IB で開こうとしたら以下のエラーが出て開けなくなった。

Interface Builder was unable to determine the type of MainWindow.xib


ググッてもよく分からず、とりあえず再起動前の状態に Git からファイルを戻した。それで治った。


ファイル壊れてたぽい。オソロシス。

EC2にRedmine入れて動かした記録

新しいプロジェクトで Rails製のBTSであるRedmineをEC2に導入したので備忘録


作業ログ

事前に AWS の webコンソールから以下の作業を行っておく。

  1. ElasticIP(固定IP) を振る。
  2. SecurityGroup で 80番ポートを開けておく。

% yum install gcc gcc-c++ kernel-devel
% yum install make
% yum install svn
% yum install ruby-devel
% yum install rubygems
% yum install sqlite-devel
% gem install rails -v=2.3.11
% gem install rack -v=1.0.1
% gem install i18n -v=0.4.2
% gem install sqlite3
% mkdir /var/lib/rails
% cd /var/lib/rails
% svn checkout http://redmine.rubyforge.org/svn/branches/1.2-stable
% mv 1.2-stable redmine-1.2
% cd redmine-1.2
% cp config/database.yml.example config/database.yml
% vi config/database.yml
 production 内を
  adapter: sqlite3
  database: db/test.sqlite3
 に変更


% rake config/initializers/session_store.rb

ここでエラー発生


WARNING: 'task :t, arg, :needs => [deps]' is deprecated. Please use 'task :t, [args] => [deps]' instead. at /var/lib/rails/redmine-1.2/lib/tasks/email.rake:170


rake のバージョン下げないとエラーになるので下げる

% gem uninstall rake
% gem install rake -v=0.8.7

引き続き

% rake config/initializers/session_store.rb
% rake db:migrate RAILS_ENV="production"
% rake redmine:load_default_data RAILS_ENV="production"
% RAILS_ENV=production ./script/server -p 80


先ほど振った固定IPでアクセスできたら成功!


※追記
この状態だと、ターミナル落としたら WEBrick 落ちちゃってアクセスできないので、デーモン化する。

% gem install mongrel
して
RAILS_ENV=production ./script/server -d -p 80
でOK

止める場合は
ps ax | grep ruby
mongrelのpid取得して

kill {pid}


以上!

一つのdevアカウントで複数Macにて実機インストールする覚書

必要な時に手順忘れる部類なので覚書。

既に1台のMacで実機開発できている事が前提。


証明書の移行手順

上記サイトに書いてあるとおり。


既に実機開発ができているマシンでの作業

  1. キーチェーンアクセスを立ち上げて、ログイン項目の証明書欄を開く
  2. iPhone Developerの証明書に含まれる暗号鍵を右クリックして、「証明書を書き出す」を選択する
  3. 証明書を個人情報交換(.p12)で、パスワード設定して保存 (.p12ファイル)
  4. 何らかの手段で先ほどの .p12 ファイルを別Macへ送る


これから実機開発したいマシンでの作業

  1. 先ほど送った .p12 ファイルをダブルクリックしてパスワード入力


※2011/12/12 追記
3台目以降に追加したい場合は、2台目から証明書を持ってきても駄目。
オリジナルである1台目の証明書しか正式なものとして認識されない。

プロファイルの移行手順

証明書の移行が終わった後で、メインマシンで新しいアプリのプロファイルを作成した場合、この作業が必要になる。


既に実機開発ができているマシンでの作業

  1. Xcodeでオーガナイザを開く
  2. DEVELOPMENTメニューのDeveloper Profileを選択
  3. 下の方にある Export Developer Profile... を選択し、任意の名前で保存(.developerprofileファイル)
  4. 何らかの手段で先ほどの .developerprofile ファイルを別Macへ送る


これから実機開発したいマシンでの作業

  1. Xcodeでオーガナイザを開く
  2. DEVELOPMENTメニューのDeveloper Profileを選択
  3. 下の方にある Import Developer Profile... を選択して、先程送った .developerprofile ファイルを選択

※ info.plist の BundleIdentifier を合わせるのも忘れずに。

(これやんないとターゲット > 情報を見る で目的のプロファイル選べない)



以上!

Xcode3とarmv6とarmv7とビルドに関する話

まだまだXcode3系使われてる方もいると思うので、今回詰んだ話しを。

やりたかった事

OpenSSL をアプリで利用したかったので、
http://www.x2on.de/2010/07/13/tutorial-iphone-app-with-compiled-openssl-1-0-0a-library/ などを参考に、armv6用でビルドした。


さてリリース、となった時、とある事情で別のマシンでリリースビルドは行う事となった。


‥ところが、リリースビルドが通らない。自分のマシンではビルドが通っているにも関わらず別マシンでは通らない。という事で、その原因を調べた。

調べた

自分のマシンに入っていたのは、Xcode3.2.5

リリース用ビルドを行っていたのはXcode3.2.6

こっちのマシンだと、

file was built for archive which is not the architecture being linked (armv7)

というビルドエラーが出て通らない。


そもそも armv6 とか armv7 とかは何かというと、CPUのアーキテクチャらしい。
iPhone3G までが armv6 で 3GS, 4 は armv7 ということ。

Xcode3.2.6 は armv6 対応してないのかー!と思ったら、

ちゃんと設定はある。


で、いろいろ試したら以下のような結果になった。 (※全て実機ビルド)

■Xcode3.2.5
Debug-armv6 OK
Debug-armv7 OK
AdHoc-armv6 OK
AdHoc-armv7 OK
Release-armv6 OK
Release-armv7 OK

■Xcode3.2.6
Debug-armv6 OK
Debug-armv7 NG
AdHoc-armv6 NG
AdHoc-armv7 NG
Release-armv6 NG
Release-armv7 NG

なぜか Debug-armv6 はビルド成功する。バグだろうか?


という事で、3Gにはまだ対応したかったので、OpenSSLをarmv6 と armv7 (Simulator用も) の3種類ビルドして突っ込んだ。
後はパス通ってれば勝手に使えるやつを使ってくれる。
(ただしこの方法だと warning は残る)

結論

Xcode4 からは armv6未対応って事らしいので、その前身になるバージョンに影響があったという事なんだろうか?


まだまだ3G対応は必要になる事もあるでしょうし、Xcode3.2.6 使ってる方もいると思いますので、静的ライブラリを組み込む際は複数アーキテクチャ分ビルドしたらいいですね。

libcurlのC-APIでFTPしてMLSDコマンドで詳細なリストを取る方法

分かると簡単なんだけど悶絶したので備忘録&日本語情報なさげだったので。



やりたかった事

libcurlのC用のAPIを使ってFTP接続し、各ディレクトリのリストを取りたい。


使用したlibcurlバージョン:libcurl 7.19.7
僕が使用している某サーバはFTPサーバとして ProFTPD を使用(バージョンは不明)
開発環境はmac os x 10.6.6



試した事

libcurl example - ftpgetresp.c
ここにサンプルがあったのでとりあえずこの通りにしてみた。
(サンプルはレスポンスをファイルに書きこむ内容)

レスポンスを見ると、

drwx---r-x 2 hogeUser fugaGroup 4096 Mar 8 14:15 testDir

普通に取れた。よしよしと思ってたけど、よく見ると
年が無い。

更に、少し古いファイルを取得してみたら、

-rw-r--r-- 1 hogeUser fugaGroup 4152 Aug 1 2010 test.html

年はある。でも時間がなくなった。

どうやら今年のファイルは年が省略されて、去年以前は年が入る代わりに時間が省略されるらしい(なんだこれ)。


どうやったら日時に関する全情報が取れるのだろう。ProFTPDのマニュアルを見てみる。
ProFTPD Supported FTP Commands

MDTM, SITEコマンドのUTIME なんかで取れそう。でもファイル単位。
取りたいのはディレクトリのリスト。



調べた

とりあえず、FEATコマンドで、サーバが対応しているコマンドを取得してみる。


libcurl で用意されているAPIは、curl_easy_setoptという関数になる。
libcurl - curl_easy_setopt()
マニュアルの FTP OPTIONS 項目を見ると、CURLOPT_QUOTEというオプションで実行したいコマンドを指定すればいいらしい。

CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "ftp://ftp.example.com/");
// この行でオプションを設定
curl_easy_setopt(curl, CURLOPT_QUOTE, "FEAT");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}

これでFEATコマンドが実行されて、結果をファイルなりコンソールなりに書きだして見てみる、と。

> FEAT< 211-Features:< MDTM< MFMT< AUTH TLS< MFF modify;UNIX.group;UNIX.mode;< MLST modify*;perm*;size*;type*;unique*;UNIX.group*;UNIX.mode*;UNIX.owner*;< PBSZ< PROT< REST STREAM< SIZE

という結果が返された。MDTMはサポートしてるぽいけど、これはファイル単位なので除外。



Filezilla のログを見てみた

Filezillaでログインすると、日時は当然年月日時刻まで全て表示されているので、何かしら方法があるはず。
目的のサーバにFilezillaでログインしてみて、ログを確認。

コマンド: PBSZ 0
応答: 200 PBSZ 0 successful
コマンド: PROT P
応答: 200 Protection set to Private
状態: 接続されました
状態: ディレクトリーの一覧を読み出しています...
コマンド: PWD
応答: 257 "/" is the current directory
コマンド: TYPE I
応答: 200 Type set to I
コマンド: PASV
応答: 227 Entering Passive Mode (***,***,**,**,***,**).
コマンド: MLSD
応答: 150 Opening ASCII mode data connection for MLSD
応答: 226 Transfer complete
状態: ディレクトリー一覧の表示成功

(以上一部抜粋)

どうやら MLSD というコマンドを発行している様子。

ググってみたところ、このコマンドは通常の LIST コマンドに変わる、詳細なリストを取得する比較的新しいコマンドのようである。

これで最終更新日のタイムスタンプを取得できる。



libcurl APIで実行してみた

早速やってみる。

CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "ftp://ftp.example.com/");
// この行でオプションを設定
curl_easy_setopt(curl, CURLOPT_QUOTE, "MLSD");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}


しかし、エラーが返って来た。

> MLSD< 425 Unable to build data connection: Invalid argument

どうやらコネクション確立する前にコマンド発行しているのでエラーになっている様子。


ここでひたすら悩んだ。
明示的に PASV コマンドもオプションで入れてみたりもした。けど駄目だった。


そして結局解決した方法が…



libcurl APIでのMLSDコマンド実行方法

CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "ftp://ftp.example.com/");
// このオプションでMLSDコマンドは指定する必要がある
curl_easy_setopt(curl_, CURLOPT_CUSTOMREQUEST, "MLSD");
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}

この CURLOPT_CUSTOMREQUESTというオプション、マニュアルの FTP OPTIONS のところには記述されてなくて、PROTOCOL OPTIONS 欄に書いてあったんですねー。

FEATコマンドでこのコマンドが返ってこなかったのは、MLSDコマンドが新しいコマンドゆえ、FEATに含まれていないものかと思いました。


…これが分からなくて泣いた。


以上、libcurlのC-APIを使ってMLSDコマンドでタイムスタンプを取る方法でした。
@shivaken さんのサポートがあってここまで辿りつけました。RESPECT!