Objective-Cで非同期通信を行なってAPIを叩くなどする場合はどうやるのか。
まず2つ変数を用意する。
@implementation Hogeee {
NSMutableData *hogeData;
NSURLConnection connection;
}
- (id)init {
self = [super init];
if (self != nil) {
// 初期化
hogeData = [[NSMutableData alloc] initWithCapacity:0];
}
return self;
}
hogeDataは、取得したデータ文字列を取得し、蓄積するためのもの。
JavaScriptやPHPなどでAPIからデータを取得していた人間からするとやり方に馴染みが無いが、とにかくコードを順に追っていこう。
最後にはきっと理解できる。
NSString *originURL = @"http://demo.example.com/api/gethoge?q=gyogyogyo";
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:originURL]];
if (connection) [connection cancel]; // 現在リクエスト中ならそれを一度キャンセルする
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[connection start];
これでリクエストを実行する。
取得は段階を踏む。
- 初めてレスポンスを受け取る -> didReceiveResponse
ここでhogeDataを初期化 - データを受け取る度に呼び出される -> didReceiveData
帰ってくるデータは断片なので、それをhogeDataにスタックし続ける - データを全て受け取ると呼び出される -> connectionDidFinishLoading
スタックしたデータを変換して利用する
// レスポンスを受け取った時点で呼び出される。データ受信よりも前なので注意
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[hogeData setLength:0];
}
// データを受け取る度に呼び出される
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[hogeData appendData:data];
}
// データを全て受け取ると呼び出される
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// 取得したJSON文字列を一旦dataに変換します
NSString *json_str = [[NSString alloc] initWithData:hogeData encoding:NSUTF8StringEncoding];
NSData *data = [json_str dataUsingEncoding:NSUTF8StringEncoding];
NSError *error=nil;
// JSONデータを辞書型に変換
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
// ここで別のメソッドを呼んだり、delgeteのメソッドを呼んだりしよう・・・
}
確かこれ以外にも、デリゲートメソッドはあったと思う。
NSURLConnectionの一部はdeprecatedになっているから注意しよう(iOS5かららしい)。
http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSURLConnectionDelegate_Protocol/Reference/Reference.html