最初のiOSアプリがやっと完成しそう(その3):OAuth認証のクラスをアプリから切り出しスタティックライブラリ化
OAuth認証機能のライブラリ切り出し
はてなダイアリーのアプリが一通りできた後、OAuth認証の部分は、これ以降のアプリでも使い回したいので、スタディックライブラリにしようと考えました。
最初からそれを見越して、アプリ部分とライブラリ部分とに、分けて作ればよかったのですが、不慣れで最初からそんなところまで気が回る余裕が無く、アプリができてきたころに、それを2つに分離するという、面倒な作業でした。
以前は、xcodeで、アプリのProjectの中に、スタティックライブラリのProjectを取込むように構成していたのが一般的だったようですが、
現在は(xcode4.xから?)、アプリのProjectと、スタティックライブラリのProjectの両者を、上位に"Workspace"というものを作って、この下で、両者を並行して管理できるようになったようです。
早速、workspaceを新規作成し、その下に、これまで作成してきた、はてなダイアリーのアプリのProjectを読み込みました。
次に同じworkspaceの下に、スタティックライブラリ用のProjectを新規作成し追加しました。
そして、アプリの中の、OAuth認証部分の一連のクラスを、アプリのProjectの外にだし、スタディックライブラリのProject内に移しました。
アプリのProjectから、スタディックライブラリのProjectの中のクラスを参照/利用するには、それだけではだめで、いろいろ設定がいります。この方法が最初わからず、苦労しました。→詳細
やっとアプリ/スタティックライブラリ分離版で、正常に動作するようになった後、OAuth認証のスタディックライブラリ部分を、githubで公開しました。
アプリをAppStoreにアップロードするときのアーカイブ作成で問題発生
ここまで来れば、あとはアプリをAppStoreに公開するだけだ、とその準備を進めました。
遅ればせながらDeveloper Programにも登録し、iTunes Connectでアプリの登録もすませた後、アプリをアップロードするためのアーカイブを実行したところで、エラーになりました。
スタディックライブラリ側のヘッダーファイル(*.h)が、アプリ側から見つからないというエラーです。
Run, Test等(Developスキーム)では、シミュレータでも実機でも、なにも問題なく実行できていたので、アーカイブ(Releaseスキーム)でエラーになることに、面食らいました。
ぐぐってみると、他にも同様な問題があげておられる方々がおられ、xcodeでは一般的な問題のように感じました。しかし、さらに調べても、原因と有効な対策の情報があまりなく(特に日本語では)、困りました。
やっと見つけた包括的な原因/対策の記述はここです。
xcode4 - Xcode 4 can't locate public header files from static library dependancy - Stack Overflow
ここにある、下記を User Header Search Paths に追加する事で、やっと解決しました。
"$(BUILD_ROOT)/../IntermediateBuildFilesPath/UninstalledProducts"
とりあえずこれで、やっとアプリをAppStoreにアップロードできました。
最初のiOSアプリがやっと完成しそう(その2):OAuth認証
開始までの経緯
最初のiOSアプリ習作を、ブログサービス「はてなダイヤリー」のネイティブアプリとしましたが、Webサービスをアプリから使うには、ユーザ認証する必要があります。
はてなでは、いくつかの認証方法が提供されており、そのなかで、OAuth認証がおもに推奨されているようでした。
はてな OAuth - Hatena Developer Center
はてなに限らず、Web界隈で、OAuth認証が使われているサイトをよく見かけるようになっていましたので、まず手始めに、これを利用できるようにするところから始めました。
解説ページを読んでいったのですが、そもそもOAuth認証について全く知らなかったので、よく理解できませんでした。
ま、理解できずとも、どこかにiOS用のOAuthライブラリが転がっていて、それを拾ってきてブラックボックス的にアプリから使えばすむだろうと、安易に考えていました。
iOS用OAuthライブラリを探してきて試す
上記のはてなOAuth解説ページには、PerlとRubyのサンプルソースは載っていましたが、Objective-C用はありませんでした。
しかたなく、ネットで、Objective-Cで書かれたOAuthライブラリを探して、まずこれを見つけました。
他でも参照、利用されていたので、これを試しましたが、xcodeでコンパイルが通らないとか(xcodeの使い方に慣れてないだけ?)、OS X用APIが使われており、iOSでは使えないんじゃないか?とわかった、などで、すんなりいきませんでした。
必要なとこだけ抜き出して使おうと考えましたが、多数のクラスを有する、かなりマッシブなソースだったので、objective-cに不慣れなこともあり、断念。
その他のライブラリをいろいろ漁って試しましたが、どれも高機能で必要機能に絞って使いこなせないというか、動かないというか。
もっと少ないクラスで、最低限の機能に絞ったライブラリを探したところ、OAuthCoreというのを見つけ、これが解りやすそうだったのでDL。(githubではないリポジトリにあり、これを使う道草というオマケ付き。)
はてなダイアリーOAuth認証に使えるように修正
ただ単にライブラリをDLして利用するだけでは、うまくいかず、OAuthの仕組みを理解する事が早道だとおもい、結局、OAuthの仕様の資料(RFC)を読みました。
また、はてなダイアリーで動作実績のある、はてなDeveloperサイトのRubyサンプルコードを動かして、iOSプログラムと比較など試行錯誤し、iOSのコードを書いていきました。
そうしていくうち、DLしたOAuthCoreのライブラリには、はてなのOAuth認証に使うには、仕様に不足あることがわかり(*1)、最終的にこの辺りを修正して、OAuth認証のライブラリを作りました。
*1 : OAuthは認証の過程で、ユーザをログインさせるサイトにリダイレクトし誘導しますが、そのリダイレクト先のURL名( = callbackURL)を、認証文字列の生成のパラメータに含める必要がある。OAuthCoreライブラリは、それが含まれていなかった。
作成したoauthライブラリをgithubのリポジトリに登録しました。
mirie0908/iOS_oauth_library · GitHub
oauth_libraryの概要
Class : OAuthCoreWrapper
概要
OAuth認証は、以下のステップで行われる。
- iOSアプリは、サービス利用先のサーバに、Temporary Credential (=Request key and secret)のhttpリクエストを送り、これを取得する。
- iOSアプリは、取得したTemporary Credentialをつかって、サービス利用先の提供する、ログイン/認証用Webページに、ユーザをリダイレクションする。
- リダイレクションされたユーザは、このWebページでログインし、iOSアプリが同サーバのサービスを利用する事を、同サーバに許可する。
- ユーザからのこの許可を受け、同サーバは、iOSアプリに対し、verificationコードを発行する。
- サービス利用を許可されたiOSアプリは、発行されたverificationコードと、(1)で取得すみのTemporary Credentialをもって、同サーバに、これ以降サービス利用の際必要なToken Credential (=Access token and secret) のhttpリクエストを送り、これを取得する。
OAuthCoreWrapperクラスは、iOSアプリから、サービス利用したいサーバのOAuth認証のため、上記(1)および(5)の、httpリクエスト作成時に必要な、OAuthヘッダを作成する。
インスタンスメソッド
- (BOOL) getOAuthHeader4TemporaryCredentialAndStoreToProperty;
- OAuthのTemporary Credential取得用httpリクエストのための、OAuthヘッダの文字列を生成する。
- インスタンス生成・初期化の際、必要なパラメータは渡してプロパティとして持っており*1、それを使うので、このメソッドでパラメータに渡すものはありません。
*1 プロパティ
@property int oauth_status;
@property (retain) NSString *myConsumerKey; 予めサイトから取得したコンシューマkey
@property (retain) NSString *myConsumerSecret; 同 コンシューマsecret
@property (retain) NSString *myMethod; OAuthのhttpリクエスの送付メソッド(POST,GET)
@property (retain) NSURL *myURL4TemporaryCredential; TemporaryCredentialリクエスト先のURL
@property (retain) NSURL *myURL4VerifierCode;
@property (retain) NSURL *myURL4AccessCredential; TokenCredentialリクエスト先のURL
@property (retain) NSString *temporary_credential; 取得したtemporaryCredential(key)の保持用
@property (retain) NSString *temporary_credential_secret; 同secretの保持用
@property (retain) NSString *access_credential; 取得したtokenCredential(key)の保持用
@property (retain) NSString *access_credential_secret; 同secretの保持用
- (BOOL) getOAuthHeader4AccessCredentialAndStoreToPropertyWithVerifierCode:(NSString *)aVerifierCode;
- OAuthのToken Credential取得用httpリクエストのための、OAuthヘッダの文字列を生成する。
- この前のステップ(概要の4項)で取得済みのverified codeを、パラメータとして渡す。
最初のiOSアプリがやっと完成しそう
手始めに習作アプリとして、はてなダイアリーのネイティブアプリ(いまさら感あるが.....)を作ってきましたが、いつまでたっても完成しない、長い長いトンネル状態でした。
なんとか先が見えてきたので、ちょっとここで振り返り、せっかくだからこのブログ新設し、残しておく事にします。
開始したころ
iMacを買ったので、何となくiPhoneのアプリでも作ってみようかと思い立ったのが2年前。
最初の習作プログラムに、あまり深く考えず、当時使っていた、はてなダイアリーのネイティブアプリを作る事に決め、ぼちぼち必要な事を調べ始めました。
しかし、オブジェクトCもXcodeも知らない。
さらに、はてなダイアリーをアプリから利用するには、Webプログラミング特有のいろんな技術も、どうも必要だということが、だんだん分かってきて、こりゃ大変なこと始めちゃったな、と思いました。
技術
試行錯誤で調べ習得していった技術は、いろいろありますが、整理すると以下5つ。これらについて、これまでのメモ(Evernoteに殴り書き)を参考に、整理します。
- OAuth認証
- AtomPub
- Objective-C
- iOS (cocoa touch API他)
- xcodeの使い方
1、2は、(自分の理解可能な範囲では)情報もそれほど多くなく、もっとも苦労したところ。ここを中心に。
3〜5は、良書も多く、ネットでも情報多いので、多くは割愛しますが、超初心者の自分がハマったアホみたいなところを中心に。
(以下、続く)