NSURLSession
は、Appleが提供する新しくエレガントなAPIであるため、今日はNSURLConnection
を避けて使用し始めました。以前は、呼び出しNSURLRequest
をGCD
ブロックに入れて、バックグラウンドで実行していました。これが私が過去にした方法です:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURLRequest *request = [NSURLRequest requestWithURL:
[NSURL URLWithString:@"www.stackoverflow.com"]];
NSURLResponse *response;
NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error) {
// handle error
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
// do something with the data
});
});
さて、これが私がNSURLSession
を使う方法です:
- (void)viewDidLoad
{
[super viewDidLoad];
/*-----------------*
NSURLSession
*-----------------*/
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:
[NSURL URLWithString:@"https://iTunes.Apple.com/search?term=Apple&media=software"]
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:data options:0 error:nil];
NSLog(@"%@", json);
}];
}
リクエストはバックグラウンドスレッド自体で実行されるのでしょうか、それともNSURLRequest
の場合と同じ方法で独自のメカニズムを提供する必要があるのでしょうか?
いいえ、これをバックグラウンドキューにディスパッチするためにGCDを使用する必要はありません。実際、完了ブロックはバックグラウンドスレッドで実行されるため、正反対のことが当てはまります。メインキューで実行するためにそのブロック内で何かが必要な場合(たとえば、モデルオブジェクトへの同期更新、UI更新など)、次のようになります。手動でメインキューにディスパッチします。たとえば、結果のリストを取得し、これを反映するようにUIを更新すると、次のように表示される場合があります。
- (void)viewDidLoad
{
[super viewDidLoad];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"https://iTunes.Apple.com/search?term=Apple&media=software"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// this runs on background thread
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
// detect and handle errors here
// otherwise proceed with updating model and UI
dispatch_async(dispatch_get_main_queue(), ^{
self.searchResults = json[@"results"]; // update model objects on main thread
[self.tableView reloadData]; // also update UI on main thread
});
NSLog(@"%@", json);
}];
[dataTask resume];
}