SlideShare a Scribd company logo
新しい通信クラス群
NSURLSessionを使ってみる
Cocoa Study #62
Oct 19, 2013
Masayuki Nii
nii@msyk.net
13年10月18日金曜日

1
Agenda

NSURLSessionのコンセプト
NSURLConnectionとの違い
Completion Handlerを使った通信
デリゲートを使った通信

13年10月18日金曜日

2
NSURLSessionのコンセプト
と従来との違い

13年10月18日金曜日

3
iOS 7から搭載されたNSURLSession
対応するセッション(通信)

•
•
•

Default:NSURLConnectionに似た通信手法
Ephemeral:キャッシュなどに一切データを残さないの通信処理
Background:別プロセスでバックグランド処理

対応するタスク(作業)

•
•
•

Dataタスク:NSDataをアップロード、ダウンロード
Downloadタスク:通信結果をファイルへバックグランドでダウン
ロード
Uploadタスク:ファイルからバックグランドでアップロード

基本的な使い方

•
•
•

13年10月18日金曜日

NSURLSessionConfigurationクラスのセッションの設定を用意
NSURLSessionクラスのインスタンスを生成
NSURLSessionTaskクラスを取得して通信
4
NSURLConnectionとの違い
デリゲートは必須でなくなった

•

簡単な処理はシンプルに記述できる

バックグランド動作が可能になった

•

アプリケーションが終了しても通信を続ける

セッションとタスクに分かれた

•

証明書と認証の処理が別々のデリゲートで処理できるようになる

NSDataだけでなく、ファイルやストリームも入出力と
して指定できるようになった
デリゲートが比較的整理された
13年10月18日金曜日

5
通信部分の攻略法はどうなる?

新たに作る物で、NSURLConnectionを使う理由はない

•

ただし、iOS 7以降対応版である場合

従来のプログラムのNSURLConnectionはそのまま動く

•

だとしたら、無理にNSURLSessionにする必要もない

We think...

•
•

13年10月18日金曜日

たぶん、2つのやり方が併用されるのは相当先まで続くだろう
けど、サードパーティのライブラリが使われる比率は減る

6
Completion Handlerを使っ
た通信

13年10月18日金曜日

7
NSURLSessionConfigurationクラス

セッションのタイプに応じた以下のスタティクメソッド
で生成

•
•
•

+ backgroundSessionConfiguration:
+ defaultSessionConfiguration
+ ephemeralSessionConfiguration

多数のプロパティがあり生成後に修正

•
•
•

13年10月18日金曜日

HTTPのヘッダ、携帯回線の可否、タイムアウト、クッキーの扱い
TSL対応プロトコル、キャッシュや認証情報の保持
並列接続数、パイプライン、プロキシ

8
NSURLSessionクラス
オブジェクトの生成

•
•
•

+ sessionWithConfiguration:
+ sessionWithConfiguration:delegate:delegateQueue:
+ sharedSession

デリゲートとデリゲートキュー

•
•

デリゲートはなくてもOKとなっている
デリゲートキューにnilを指定するとシステムが与える

NSURLSessionタスクの生成

•
•
•
•
•

13年10月18日金曜日

タスクのタイプに応じて多数のメソッドが定義されている
生成されるのは、NSURLSessionDataTask、
NSURLSessionDownloadTask、NSURLSessionUplodadTaskのいずれか
NSURL、あるいはNSURLRequestを通信先で指定する
Completion Handler(通信後に呼び出されるブロック)を使う場合には多
くのデリゲートは呼び出されない
ハンドラ内は別スレッドで通信されるので、UIKitの処理に気をつける
9
デリゲートを指定しない通信
NSURL *currentURL = [NSURL URLWithString: @"http://msyk.net"];
NSURLSessionConfiguration *config
= [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session
= [NSURLSession sessionWithConfiguration: config
delegate: nil
delegateQueue: nil];
NSURLSessionDataTask *task
= [session dataTaskWithURL: currentURL
completionHandler: ^(NSData *data,
NSURLResponse *response,
NSError *error){
//通信後に呼び出されるブロック-Completion Handler
//引数から通信結果が得られる。処理は別スレッド
[session invalidateAndCancel];

}];
[task resume];

13年10月18日金曜日

10
デリゲート無しの場合の注意

Completion Handlerは「別スレッド」で処理

•
•

なにもしなくても、コールバックは別スレッドになった
delegateQueueはnilの場合「Serial Operation Queue」つまり、
mainQueueで得られるメインスレッド用のキューを使う

[session invalidateAndCancel]が必要

•

マニュアルには書いてある。ないとリークするそうです

Completion Handlerを記述し、delegateもセットし
て、デリゲートメソッドを実装したら…

•

13年10月18日金曜日

デリゲートメソッドのほとんどは呼び出されない

11
NSURLSessionでタスクを返すメソッド
Adding Data Tasks to a Session

•
•
•
•

-

dataTaskWithURL:
dataTaskWithURL:completionHandler:
dataTaskWithRequest:
dataTaskWithRequest:completionHandler:

Adding Download Tasks to a Session

•
•
•
•
•
•

-

downloadTaskWithURL:
downloadTaskWithURL:completionHandler:
downloadTaskWithRequest:
downloadTaskWithRequest:completionHandler:
downloadTaskWithResumeData:
downloadTaskWithResumeData:completionHandler:

Adding Upload Tasks to a Session

•
•
•
•
•

13年10月18日金曜日

-

uploadTaskWithRequest:fromData:
uploadTaskWithRequest:fromData:completionHandler:
uploadTaskWithRequest:fromFile:
uploadTaskWithRequest:fromFile:completionHandler:
uploadTaskWithStreamedRequest:
12
NSURLSessionの既定の動作

タスクにCompletion Handlerを実装した場合

•
•
•
•

通常のHTTP通信は、リダイレクトを含めてそのまま可能
サーバ証明書が正しいHTTPS通信もそのまま可能
サーバ証明書が正しくない場合(おれおれ証明書)、通信はでき
ず、-1202番のエラーを返す
認証が絡む場合デリゲートでの実装が一般的

デリゲートで実装する場合

•
•

13年10月18日金曜日

通信中のプログレス表示などが可能になる
デフォルトの動作をさせたい場合は対応するデリゲートメソッドは
実装しない

13
デリゲートを実装してみる

13年10月18日金曜日

14
デリゲートで記述可能なメソッド
URLSessionDelegate(セッション)

•
•
•

- URLSession:didBecomeInvalidWithError:
- URLSession:didReceiveChallenge:completionHandler:
- URLSessionDidFinishEventsForBackgroundURLSession:

URLSessionTaskDelegate(タスク一般)

•
•
•
•
•

-

URLSession:task:didCompleteWithError:
URLSession:task:didReceiveChallenge:completionHandler:
URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:
URLSession:task:needNewBodyStream:
URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:

URLSessionDataDelegate(データとアップロードタスク)

•
•
•
•

-

URLSession:dataTask:didReceiveResponse:completionHandler:
URLSession:dataTask:didBecomeDownloadTask:
URLSession:dataTask:didReceiveData:
URLSession:dataTask:willCacheResponse:completionHandler:

URLSessionDownloadDelegate(ダウンロードタスク)

•

- cancelByProducingResumeData:

返り値の指定

•

13年10月18日金曜日

completionHandler:の引数にあるブロックに引数を与えて呼び出す(returnじゃない!)
15
デリゲートを実装したときの一般的な通信処理

デリゲートの呼び出し結果

•
•
•
•
•

urlString = http://msyk.dyndns.org/test.php
-[Communication
URLSession:dataTask:didReceiveResponse:completionHandle
r:]
-[Communication URLSession:dataTask:didReceiveData:]
:
-[Communication URLSession:task:didCompleteWithError:]

We think...

•

13年10月18日金曜日

以前と変わらず? 完了時の呼び出したエラーの有無で違っていな
いで1つのメソッドになった!

16
存在しないファイルにアクセスした場合
デリゲートの呼び出し結果

•
•
•
•
•
•
•

urlString = http://msyk.dyndns.org/test1.php
-[Communication
URLSession:dataTask:didReceiveResponse:completionHandler:]
HTTP Response Code = 404
-[Communication
URLSession:dataTask:willCacheResponse:completionHandler:]
-[Communication URLSession:dataTask:didReceiveData:]
-[Communication URLSession:task:didCompleteWithError:]
[error] (null)

We think...

•

13年10月18日金曜日

エラーは返さないので、レスポンスのステータスコードを見る必要が
ある
17
存在しないURLに接続しようとした
デリゲートの呼び出し結果

•
•
•

urlString = http://msyk1234.dyndns.org/
-[Communication URLSession:task:didCompleteWithError:]
[error] Error Domain=NSURLErrorDomain Code=-1003 "A
server with the specified hostname could not be found."
UserInfo=0xdb4fe70 {NSErrorFailingURLStringKey=http://
msyk.netxxxxx, NSErrorFailingURLKey=http://msyk.netxxxxx,
NSLocalizedDescription=A server with the specified hostname
could not be found., NSUnderlyingError=0x8d59160 "A
server with the specified hostname could not be found."}

We think...

•
•

13年10月18日金曜日

完了のメソッドだけがデリゲートされる
まあ、順当だろう
18
リダイレクト
デリゲートの呼び出し結果

•
•
•
•
•
•
•

urlString = http://msyk.dyndns.org/test.php
-[Communication
URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler
:]
-[Communication
URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler
:]
-[Communication
URLSession:dataTask:didReceiveResponse:completionHandler:]
-[Communication URLSession:dataTask:didReceiveData:]
:
-[Communication
URLSession:dataTask:willCacheResponse:completionHandler:]

We think...

•
•

13年10月18日金曜日

単にリダイレクトをそのままリダイレクトするならデリゲートは不要
リダイレクトがあれば、willPerformHTTPRedirectionが呼び出される
19
HTTPSと認証

13年10月18日金曜日

20
認証と証明書の対応
HTTPによるユーザ認証

•
•

タスク側で、デリゲートメソッドが呼び出される
URLSession:task:didReceiveChallenge:completionHandler:

証明書の確認処理

•
•

セッション側で、デリゲートメソッドが呼び出される
URLSession:didReceiveChallenge:completionHandler:

情報源

•
•

13年10月18日金曜日

iOS Developer Libraryの「URL Loading System Programming
Guide」にあるAuthentication Challenges and TLS Chain Validation
に詳細が記載されているが、現時点ではNSURLConnectionのみの説明
このドキュメントに掲載されているサンプルプログラムを頼りにプログ
ラムをする。このメソッドにユーザ名とパスワードを与えれば、確かに
認証は可能であるが…
21
Appleのドキュメントにある認証のためのコード

-(void)connection:(NSURLConnection *)connection
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge previousFailureCount] == 0) {
NSURLCredential *newCredential;
newCredential
= [NSURLCredential credentialWithUser:[self preferencesName]
password:[self preferencesPassword]
persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:newCredential
forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
// inform the user that the user name and password
// in the preferences are incorrect
[self showPreferencesCredentialsAreIncorrectPanel:self];
}
}

13年10月18日金曜日

22
HTTPの認証が必要なサイトへのアクセス
注意すべき点

•

Completion Handlerだけの実装の場合、通信は成功するが、レスポンスコードが401
なので認証エラーと分かる

実際に認証がになったとき

•

ユーザ名とパスワードを含めたNSURLCredentialクラスのオブジェクトを返す

デリゲートメソッドを実装した場合

•
•
•
•
•
•
•
•
•

13年10月18日金曜日

-[Communication URLSession:task:didReceiveChallenge:completionHandler:]
[authMethod]NSURLAuthenticationMethodDefault
-[Communication
URLSession:dataTask:didReceiveResponse:completionHandler:]
HTTP Response Code = 200
-[Communication URLSession:dataTask:didReceiveData:]
:
-[Communication URLSession:dataTask:willCacheResponse:completionHandler:]
-[Communication URLSession:task:didCompleteWithError:]
[error] (null)
23
認証に対応するデリゲートメソッドの例

- (void) URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,
NSURLCredential *credential))completionHandler
{
NSString *authMethod = challenge.protectionSpace.authenticationMethod;
if ( [authMethod isEqualToString: NSURLAuthenticationMethodDefault] ) {
NSURLCredential *credential
= [NSURLCredential credentialWithUser: self.username
password: self.password
persistence: NSURLCredentialPersistenceNone];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
} else {
completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
}
}

13年10月18日金曜日

24
HTTPSによる通信と証明書
注意すべき点

•
•

Completion Handlerを使用する場合、何もしなくてもOK
NSURLConnectionでは動作が大きく異なるので注意が必要

デリゲートの呼び出し結果

•
•
•
•
•

urlString = https://msyk.net/
-[Communication
URLSession:dataTask:didReceiveResponse:completionHandler:]
-[Communication URLSession:dataTask:didReceiveData:]
-[Communication URLSession:task:didCompleteWithError:]
[error] (null)

おれおれ証明書でも許可する場合

•
•

13年10月18日金曜日

デリゲートメソッドを実装して、判定して必要な結果を返す
正しい証明書の場合でも、適切な結果を返す必要がある
25
証明書に対応するデリゲートメソッドの例
Security.frameworkの追加が必要
- (void) URLSession:(NSURLSession *)session
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition,
NSURLCredential *credential))completionHandler
{
NSString *authMethod = challenge.protectionSpace.authenticationMethod;
if ( [authMethod isEqualToString: NSURLAuthenticationMethodServerTrust] ) {
SecTrustRef secTrustRef = challenge.protectionSpace.serverTrust;
if (secTrustRef != NULL)
{
SecTrustResultType result;
OSErr er = SecTrustEvaluate( secTrustRef, &result );
if ( er != noErr) {
completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
}
// nilを返した場合には通信は許可されない
if ( result == kSecTrustResultRecoverableTrustFailure ) {
NSLog( @"---SecTrustResultRecoverableTrustFailure" );
//信頼できない証明書の場合の対処をここに記述。拒否ならreturn

}

}
NSURLCredential *credential = [NSURLCredential credentialForTrust: secTrustRef];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
// NSURLCredentialクラスのオブジェクトを返せば許可したことになる

}
}
13年10月18日金曜日

26
まとめ

NSURLSessionは待ち望まれていた通信処理の大改良
デリゲート無しでの処理で概ね通信は可能
バックグランド処理やファイル直接処理は期待大

13年10月18日金曜日

27

More Related Content

PDF
【卒業論文】B2Bオークションにおけるユーザ別 入札行動予測に関する研究
PPTX
[DL輪読会]Active Domain Randomization
PDF
12. Diffusion Model の数学的基礎.pdf
PDF
大規模並列実験を支えるクラウドサービスと基盤技術
PPTX
アダルトデータマイニングの勧め
PDF
[DL輪読会]StarGAN: Unified Generative Adversarial Networks for Multi-Domain Ima...
PPTX
マルチエージェント強化学習 (MARL) と M^3RL
PPTX
[DL輪読会]SOLAR: Deep Structured Representations for Model-Based Reinforcement L...
【卒業論文】B2Bオークションにおけるユーザ別 入札行動予測に関する研究
[DL輪読会]Active Domain Randomization
12. Diffusion Model の数学的基礎.pdf
大規模並列実験を支えるクラウドサービスと基盤技術
アダルトデータマイニングの勧め
[DL輪読会]StarGAN: Unified Generative Adversarial Networks for Multi-Domain Ima...
マルチエージェント強化学習 (MARL) と M^3RL
[DL輪読会]SOLAR: Deep Structured Representations for Model-Based Reinforcement L...

What's hot (20)

PPTX
最尤推定法(NNでの応用)
PDF
[DL輪読会]Deep Neural Networks as Gaussian Processes
PDF
GANの概要とDCGANのアーキテクチャ/アルゴリズム
PDF
深層強化学習でマルチエージェント学習(後篇)
PDF
[DL輪読会]Learning Task Informed Abstractions
PDF
SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜
PDF
ゼロから始める深層強化学習(NLP2018講演資料)/ Introduction of Deep Reinforcement Learning
PPTX
[DL輪読会]Social Influence as Intrinsic Motivation for Multi-Agent Deep Reinforc...
PDF
continual learning survey
PDF
SSII2019TS: Shall We GANs?​ ~GANの基礎から最近の研究まで~
PDF
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...
PDF
【DL輪読会】ConvNeXt V2: Co-designing and Scaling ConvNets with Masked Autoencoders
PDF
프로그래머가 되고 싶으세요
PDF
行列およびテンソルデータに対する機械学習(数理助教の会 2011/11/28)
PDF
[DL輪読会]Understanding Black-box Predictions via Influence Functions
PPTX
MS COCO Dataset Introduction
PPTX
Long-Tailed Classificationの最新動向について
PDF
最近思った機械学習(PyTorch)のベストプラクティス
PDF
[DL輪読会] Spectral Norm Regularization for Improving the Generalizability of De...
PDF
深層強化学習の self-playで、複雑な行動を機械に学習させたい!
最尤推定法(NNでの応用)
[DL輪読会]Deep Neural Networks as Gaussian Processes
GANの概要とDCGANのアーキテクチャ/アルゴリズム
深層強化学習でマルチエージェント学習(後篇)
[DL輪読会]Learning Task Informed Abstractions
SSII2021 [TS2] 深層強化学習 〜 強化学習の基礎から応用まで 〜
ゼロから始める深層強化学習(NLP2018講演資料)/ Introduction of Deep Reinforcement Learning
[DL輪読会]Social Influence as Intrinsic Motivation for Multi-Agent Deep Reinforc...
continual learning survey
SSII2019TS: Shall We GANs?​ ~GANの基礎から最近の研究まで~
Word Tour: One-dimensional Word Embeddings via the Traveling Salesman Problem...
【DL輪読会】ConvNeXt V2: Co-designing and Scaling ConvNets with Masked Autoencoders
프로그래머가 되고 싶으세요
行列およびテンソルデータに対する機械学習(数理助教の会 2011/11/28)
[DL輪読会]Understanding Black-box Predictions via Influence Functions
MS COCO Dataset Introduction
Long-Tailed Classificationの最新動向について
最近思った機械学習(PyTorch)のベストプラクティス
[DL輪読会] Spectral Norm Regularization for Improving the Generalizability of De...
深層強化学習の self-playで、複雑な行動を機械に学習させたい!
Ad

Similar to Cocoa勉強会#62-新しい通信クラス群NSURLSessionを使ってみる (6)

PDF
yidev#14 NSURLSession
PDF
Cocoa勉強会#61-メインスレッド外でNSURLConnection
PDF
iOSハンズオントレーニング通信(NSURLConnection/NSURLSession)編
PDF
20120721_ishkawa
PDF
GameKitを使ったBluetoothプログラミング
PDF
美味しく画像を頂きたい
yidev#14 NSURLSession
Cocoa勉強会#61-メインスレッド外でNSURLConnection
iOSハンズオントレーニング通信(NSURLConnection/NSURLSession)編
20120721_ishkawa
GameKitを使ったBluetoothプログラミング
美味しく画像を頂きたい
Ad

More from Masayuki Nii (20)

PDF
Framework Enabling End-Users to Maintain Web Applications (ICICWS2015)
PDF
トップエスイー勉強会2014第1回-INTER-Mediator
PDF
Cocoa勉強会#34-iPhoneでタブバーを非表示に無理矢理する方法
PDF
Cocoa勉強会#23-カスタムシートとModality
PDF
Cocoa勉強会#6-SQLiteをCocoaで使う
PDF
Cocoa勉強会#60-Common Cryptoを使った共通鍵の暗号と復号
PDF
Cocoa勉強会#57-Baseによるローカライズまとめ
PDF
Cocoa勉強会#56-小ネタ集あなたの常識はすでに通用しない
PDF
Cocoa勉強会#45-AWS SimpleDBを使ってみる
PDF
Cocoa勉強会#36-iPhone OS 3.0で変更されたテーブルビュー
PDF
Cocoa勉強会#33-意外に楽に使えるlibcurl
PDF
Cocoa勉強会#28-OpenSSLで暗号化したファイルを復号する
PDF
Cocoa勉強会#27-QuickLookプラグインの作り方
PDF
Cocoa勉強会23-識別情報の変換〜文字エンコードとデータタイプ
PDF
Cocoa勉強会#37-シェイクイベントの実装
PDF
Cocoa勉強会#32-表形式のデータに順序を記録する方法
PDF
Cocoa勉強会#35-iPhoneでのコピペとカスタムUI
PDF
Cocoa勉強会#47-NSURLConnectionのデリゲートメソッドと認証
PDF
Cocoa勉強会#38-UITableViewテーブル内のナビゲーション
PDF
Cocoa勉強会#43-Blocksを使う
Framework Enabling End-Users to Maintain Web Applications (ICICWS2015)
トップエスイー勉強会2014第1回-INTER-Mediator
Cocoa勉強会#34-iPhoneでタブバーを非表示に無理矢理する方法
Cocoa勉強会#23-カスタムシートとModality
Cocoa勉強会#6-SQLiteをCocoaで使う
Cocoa勉強会#60-Common Cryptoを使った共通鍵の暗号と復号
Cocoa勉強会#57-Baseによるローカライズまとめ
Cocoa勉強会#56-小ネタ集あなたの常識はすでに通用しない
Cocoa勉強会#45-AWS SimpleDBを使ってみる
Cocoa勉強会#36-iPhone OS 3.0で変更されたテーブルビュー
Cocoa勉強会#33-意外に楽に使えるlibcurl
Cocoa勉強会#28-OpenSSLで暗号化したファイルを復号する
Cocoa勉強会#27-QuickLookプラグインの作り方
Cocoa勉強会23-識別情報の変換〜文字エンコードとデータタイプ
Cocoa勉強会#37-シェイクイベントの実装
Cocoa勉強会#32-表形式のデータに順序を記録する方法
Cocoa勉強会#35-iPhoneでのコピペとカスタムUI
Cocoa勉強会#47-NSURLConnectionのデリゲートメソッドと認証
Cocoa勉強会#38-UITableViewテーブル内のナビゲーション
Cocoa勉強会#43-Blocksを使う

Cocoa勉強会#62-新しい通信クラス群NSURLSessionを使ってみる