Copyright (C) iPhoneアプリ開発備忘録 All rights reserved.
ブログ内で記したコード、内容の正確性は保証いたしません。
記載内容を実装したことにより発生した不具合・損害等の責任は一切負いません。



2016年05月22日

最も簡単なNSURLConnectionからNSURLSessionへの移行



2016年6月1日より、AppleはApp Stoteで配信するアプリについて、IPv6サポート対応必須を義務付けた。
従って、IPv6をサポートしないNSURLConnectionを通信に使用しているアプリは2016年6月1日以降の審査提出分について、リジェクトされる。

Supporting IPv6-only Networks
https://developer.apple.com/news/?id=05042016a

Supporting IPv6 in iOS 9
https://developer.apple.com/news/?id=08282015a

いずれ今後のiOSメジャーアップデートで、IPv6をサポートしないアプリは動作しなくなる可能性があることから、IPv6をサポートしないNSURLConnectionから、IPv6をサポートするNSURLSession またはCFNetworkを使用して通信するように改修が必要である。

NSURLSessionではバックグラウンドでデータをダウンロード・アップロードしたりと多くの機能を持つが、NSURLConnectionを使って単なるデータのダウンロードをしているだけの機能を有する場合は、移行は比較的簡単である。

hogeViewController.h
<変更前>
@interface hogeViewController : UIViewController <NSURLConnectionDelegate>
{
@property (nonatomic, retain) NSMutableData *data; // ダウンロードしたデータの格納先
}


<変更後>
@interface hogeViewController : UIViewController <NSURLSessionDelegate>
{
@property (nonatomic, retain) NSMutableData *data; // ダウンロードしたデータの格納先
}



hogeViewController.m
1. ダウンロードの開始
<変更前>
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://hoge.com/"]]; // ダウンロードURLの作成
NSURLConnection *feedConnection = [[NSURLConnection alloc] initWithRequest: urlRequest delegate:self]; // ダウンロードの開始


<変更後>
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://hoge.com/"]]; // ダウンロードURLの作成
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; // セッションの種類
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration
delegate:self
delegateQueue:[NSOperationQueue mainQueue]]; // セッションの作成
NSURLSessionDataTask *task = [session dataTaskWithRequest: urlRequest]; // タスクの作成
[task resume]; // タスクの実行



2. ダウンロードの開始直後
<変更前>
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
self.data = [[NSMutableData data] init]; // ダウンロードしたデータの格納先を初期化
}


<変更後>
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
self.data = [[NSMutableData data] init]; // ダウンロードしたデータの格納先を初期化

completionHandler(NSURLSessionResponseAllow); // didReceivedData と didCompleteWithErrorが呼ばれるように定数を処理継続のハンドラーに渡す
}



3. ダウンロードされたデータの追加
<変更前>
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.data appendData:data];
}


<変更後>
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
[self.data appendData:data];
}



4. ダウンロードエラーの通知
<変更前>
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {

if ([error code] == kCFURLErrorNotConnectedToInternet) {

} else {

}
}


<変更後>
NSURLSessionでは、「5. ダウンロード完了通知」に示す
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
で、ダウンロード完了通知とエラー通知を同時に受け取る。


5. ダウンロード完了通知
<変更前>
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {


<変更後>
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
if (error) {
// エラー処理
} else {
// ダウンロードされたデータのパースなどの処理
}
}



- (void)URLSession:(NSURLSession *)session
downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
でダウンロード完了通知を受け取ることも可能だが、上記事例ではこのデリゲートは呼ばれない。

参考記事:
http://qiita.com/akitaika_/items/2f4fca20a82cb6895329
http://qiita.com/aKentaKoyama/items/96a979ab3a140e7b39ec
https://www.gaprot.jp/pickup/ios7/background-fetch
http://blog.techfirm.co.jp/2013/11/25/ios-7-nsurlsessionでバックグラウンド通信をする/
 
 


タグ:Mac apple iPAD IOS iPhone
【NSURLSessionの最新記事】
posted by mobileDeveloper at 12:35 | Comment(2) | TrackBack(0) | NSURLSession はてなブックマーク - 最も簡単なNSURLConnectionからNSURLSessionへの移行 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
Posted by at 2016年05月23日 14:54
質問なのですが、NSURLConnectionがIPv6をサポートしないというのは、
またはNSURLConnectionを使用している場合リジェクトされるというのは公式の情報でしょうか?

>>>>
because IPv6 is already supported by NSURLSession and CFNetwork APIs.
>>>>
を読む限り、NSURLConnectionもCFNetworkの一つなので、IPv6に対応してると思われますが・・
Posted by bebe at 2016年06月17日 12:53
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック
Apple、Appleのロゴ、App Store、iPodのロゴ、iTunesは、米国および他国のApple Inc.の登録商標です。
iPhone、iPod touch、iPadはApple Inc.の商標です。
iPhone商標は、アイホン株式会社のライセンスに基づき使用されています。
その他、本ブログに記載されている製品名、会社名は、それぞれ各社の商標または登録商標です。