0

NSURLSessionConfiguration::protocolClassesの文書によると、私のカスタムURLプロトコルが使用される保証はありません。 protocolClassesプロパティに設定するたびに、どのように使用されるのかをどうすれば保証できますか?私のカスタムURLプロトコルが使用されていることを確認するにはどうすればいいですか?

要求を処理する前に、NSURLSessionオブジェクトが最初 デフォルトのプロトコルを検索し、 は、指定された要求を処理することができるものを見つけ、それまでは、カスタム・プロトコルをチェックします。それは プロトコルを使用します。このプロトコルでは、canInitWithRequest:classメソッドがYESを返します。 は、クラスが指定された リクエストを処理できることを示します。

ロジックがcanInitWithRequest:メソッドであり、すべてのリクエストを処理できないため、単一URLプロトコルで配列を設定できません。

NSArray *currentProtocolClasses = sessionConfiguration.protocolClasses ?: @[]; 
NSMutableArray *protocolClasses = [NSMutableArray arrayWithArray:currentProtocolClasses]; 
[protocolClasses insertObject:[CustomURLProtocol class] atIndex:0]; 
sessionConfiguration.protocolClasses = protocolClasses; 

答えて

1

ドキュメントによれば、それはバグです。ファイルしてください。ロジックは、そこに記載されているものよりもはるかに単純です。基本的にはOSはこれです:

NSURLProtocol *protocol = nil; 
for (Class protocolClass in sessionConfiguration.protocolClasses) { 
    if ([protocolClass canInitWithRequest:request]) { 
     protocol = [[protocolClass alloc] init]; 
    } 
} 
if (!protocol) { 
    fail 
} 

あなたのプロトコルが最初にリストされている限り、それらは優先されます。 (NSURLConnectionについては、その文書のビットも間違っていたので、組み込みプロトコルの前に登録されたプロトコルが常に最初に尋ねられます)。

標準プロトコルを処理する必要がない場合は、これを行うには:

sessionConfiguration.protocolClasses = @[[CustomURLProtocol class]]; 

URLプロトコルを強制的に使用することはできません。このプロトコルは、そのcanInitWithRequest:クラスメソッドが要求に対してYESを返す場合にのみ使用されます。別のプロトコルにリクエストを処理させたい場合(通常、実際に通常のhttpsリクエストを使用するカスタムURLスキームを定義する場合など)、通常はURLを書き換えてリクエストを再発行するプロトコルを作成しますプロトコルハンドラクラスがインストールされていない新しいセッション。

また、何らかの方法で要求を変更する限り、ハンドラをインストールしたセッションで要求を再発行して、プロトコルハンドラが要求をもう一度見たときにcanInitWithRequest:メソッドからNOを返すことがわかるようにすることができます。 (そうでなければ、無限の再帰を得るでしょう)

+0

こんにちは!より包括的にするために、サンプルコードを 'sessionConfiguration.protocolClasses = @ [[CustomURLProtocol class]];に変更してください。ありがとう – JastinBall

+1

ええ、確かに。完了しました。 – dgatwood

+0

"配列は常に空またはnil"について:私はデフォルトのsessionConfigurationを作成します。そのprotocolClasses配列はすでに5つのOSプロトコルを含んでいます: '_NSURLHTTPProtocol'、' _NSURLDataProtocol'、 '_NSURLFTPProtocol'、' _NSURLFileProtocol'、 'NSAboutURLProtocol'。私は 'CustomURLProtocol'を追加する必要があります。私の 'CustomURLProtocol'が' canInitWithRequest: 'にNOを返すときはいつでも、アプリケーションはOSプロトコルにフォールバックする必要があります。 – JastinBall

関連する問題