.30 2011
もういくつ寝ると除夜の鐘
いや、この記事を書いているときは明日ですよ
暮れましてこんばんは、UTOでございます。
今日はURLスキームについてまとめます。
スポンサーサイト
.26 2010
Tasakiです。
ここ最近、とても暖かいですね。いや暑いくらいです。
とても2月とは思えません。一体何が起こっているのでしょうか?
今週はSDK 3.2 beta 3 も公開され、そろそろフィックス版も近いのかなと推測していますが、ここ最近何かと出くわすことの多かった、この話題について取りあげてみます。
iPhoneは携帯電話ということで、セキュリティについては特に重視した設計になっていますが、そのために困った問題が発生することもあります。
httpsスキームが、その代表例でしょうか。
この場合、認証局の署名がされていない自己署名の証明書では、通信時にエラー扱いにされてしまいます。Macでは警告ダイアログなのに、ちょっと乱暴な気がします。
これを回避するための魔法のコードがこれです。
@implementation NSURLRequest( NSHTTPURLRequest )
+ ( BOOL ) allowsAnyHTTPSCertificateForHost:( NSString* ) host {
return YES;
}
@end
これをコードのどこかに記述しておけば、ビルド時に警告が7件くらい出るものの、自己署名証明でも問題なく通信を行うことができるようになります。
ただし、AppStoreで配布する場合には、審査を通過しないようです。うーん。
また、BASIC認証が必要なURLへUIWebViewからアクセスする場合も注意が必要です。
事前にBASIC認証のかかったサイトであることが分かっている場合は、
NSURL* url = [ NSURL URLWithString: @"http://user:password@www.test.com" ];
[ webVIew loadRequest:[ NSURLRequest requestWithURL: url ]];
と言った具合で記述しておけば、問題なく表示することが可能な訳ですが、そうでない場合には、非公開APIを利用してイベントを取得する必要があるようです。
この方法については、私自身が未検証なので、リンクだけ貼らせていただきます。
http://d.hatena.ne.jp/KishikawaKatsumi/20090603/1243968707なお、Mobile Safari では、専用の入力フォームが表示されるようになっています。なんかずるいですよね。
こんな感じで、通信部分のAPIについては、今後更なる拡充をお願いしたいところですね。
.18 2009
Tasakiです。
このところ、更新する機会を持てず3ヶ月ぶりとなってしまいました。
これからは週1では更新していきたいと考えていますので、改めまして宜しくお願い致します。
さて、今回のテーマですが、OS3.0(最新は3.1.2ですが…)で追加された機能の中でも、目玉の1つである HTTP ライブストリーミングについて、触れてみたいと思います。
映像のライブストリーミングと言えば、
RTP /
RTSPがこれまでの主流だったわけですが、iPhoneOSそしてQuickTimeXに、このテクノロジが導入されたことで、今後どうなっていくのか、個人的にも注目しています。
Appleのドキュメントにもありますが、このテクノロジの魅力は何と言っても、ほぼどのような接続環境でも問題なく視聴が可能だと言う点です。
RTPの場合は、ファイアウォールによってブロックされてしまう可能性があります。
設置型のPCならともかく、ネットブックや携帯電話は、いつ、どのような環境でネットワークに接続するかは分かりませんので、これは障害となります。
一方、どのようなネットワーク環境においても、HTTPがブロックされることは、まず考えられません。
このような点から、モバイルデバイスとの相性も良いといえます。
また、肝心の画質や途切れに関しても、予想以上の結果で非常に驚きでした。
では、実際にiPhone上に実装してみましょう。
iPhone SDKにおける動画プレイヤーといえば、MediaPlayerフレームワークのMPMoviePlayerControllerですが、これの初期化の際に、HTTPライブストリーミング用プレイリストファイルのURLを渡します。
ソースコードは以下の通りです。
NSURL* url = [ NSURL URLWithString: @"http://qthttp.apple.com.edgesuite.net/0909oijasdv/all.m3u8" ];
MPMoviePlayerController* moviePlayer = [[ MPMoviePlayerController alloc ] initWithContentURL: url ];
[ moviePlayer play ];
これをアプリのどこかに追加するだけで、OKです。非常に簡単です。
URLの部分は、ライブストリーミング用プレイリストファイルを指しています。
特にファイルでなくとも、このリクエストのレスポンスがプレイリストファイルと同等であれば構いません。
ただし、ローカルのプレイリストファイルを渡してもストリーミングはされないのでご注意ください。
ちなみに、サンプルのURLは、例の方の講演となっております。
.08 2009
Tasaki です。
今日調査して分かったことがありましたので、入門編6回目としてお送りします。
3回目と4回目でレスポンスについて触れましたが、このときにはヘッダの取得とコネクションの確立失敗に関しての話だけに留まっていました。というのも、レスポンスの中身( HTTP body )の取得の仕方が分からなかったためです。これがやっと解決しました。
connection:didReceiveResponse: メソッドはレスポンスヘッダの取得時に呼び出されるメソッドでしたが、この他にレスポンスの内容を取得したときに呼ばれるデリゲートメソッドがあります。それがこちらです。
- ( void ) connection:( NSURLConnection *) connection didReceiveData:( NSData *) data;
- ( void ) connectionDidFinishLoading:( NSURLConnection *) connection;
前者はレスポンスデータの一部または全てを引数として与え、後者は全てのデータを取得した場合に呼び出されるメソッドです。
データが単一のパケットに収まりきらない場合は connection:didReceiveData: メソッドは、部分データを逐次渡してきます。そのため、このメソッドは1度のリクエストに対し、複数回呼び出される可能性があります。
これを利用して、サーバ側でリクエストが正常に受理された場合は1を、そうでない場合には0を返すようにしていた場合、クライアントの iPhone アプリでは以下のように実装することで、受理されたかどうかを知ることができます。
- ( void ) connection:( NSURLConnection *) connection didReceiveData:( NSData *) data {
unsigned char value;
[ data getBytes: &value length: sizeof( value )];
if( value ) {
// 受理された
}
}
レスポンスデータの取得も、このように簡単に行うことができます。
ふたを開けてみれば、すごく単純な話だったのですが、デリゲートメソッドの名前をタイプミスしていたせいで、今日の今日まで全くやり方が分かりませんでした。
その中で、NSURLResponse に body を取得するメソッドがないか調べたりしていました。たったこれだけのために、CFNetwork フレームワークを使わなきゃいけないのか、と悩んだりもしました。
というわけで、今回の経験で得た教訓
「デリゲートメソッドの名前はコピペしとけ!」
.01 2009
Tasaki です。
今回でネットワークプログラミング入門編も5回目となりました。
前回までの4回で、送信と受信についてのお話は終わっていますが、今回は僕が実装中にハマった落とし穴について解説しておこうと思います。
それは、HTTP リクエスト作成時に、サーバ側へクエリとしてパラメータを渡す場合の注意点です。HTTP プロトコルを利用する場合には、
RFC1808 に従った文字列を渡す必要があります。
つまり、任意の文字列をそのまま URL として渡してよい、というわけではありません。
ここで、1番問題になりそうなのが空白文字です。これを URL に含めてしまうと、リクエスト送信時にコネクションエラーが発生してしまいます。
このような場合には、エスケープ文字を使用して文字を文字コードに置き換えておく必要があります。例えば半角スペースなら、%20といった具合です。
Cocoa には、これを簡単に実現できる以下のメソッドが用意されています。
- ( NSUInteger ) replaceOccurrencesOfString:( NSString *) target withString:( NSString *) replacement options:( NSStringCompareOptions ) opts range:( NSRange ) searchRange;
target には置換後の文字列(%20)、replacement には置換対象の文字列 (半角スペース)、opts には文字列比較オプション、searchRange には、レシーバ文字列(URL文字列)内の適用範囲を与えます。なお、返り値は置換操作の実施回数が渡されます。
これを使用して、実際に URL 文字列内の半角スペースをエスケープするコードを示します。
[ urlString replaceOccurencesOfString: @"%20" withString: @" " options: NSLiteralSearch range: NSMakeRange( 0, [ urlString length ])];
ちょっと長ったらしいですが、これを使えば1行で済んじゃいますのでとても楽です。
NSString クラスのメソッドは癖のあるものも多いですが、非常に便利なので、なるべく修得しておきたいですね。