2016-03-20 5 views
1

NSURLProtocol定義を行います。私は正確に何+ [NSURLProtocolのsetProperty:forKey:inRequest:]メソッド以下

をしかし、私は要求してNSURLAuthenticationChallengeを関連付けるしようとする場合は、次のコード

[NSURLProtocol setProperty:challenge forKey:@"challenge" inRequest:self.request]; 

を使用してログの次のエラーを参照してください:

2016-03-20 18:00:41.252 [email protected][6084:586155] ERROR: createEncodedCachedResponseAndRequestForXPCTransmission - Invalid protocol-property list - CFURLRequestRef. protoProps=<CFBasicHash 0x7f98ec6dcca0 [0x10684e180]>{type = mutable dict, count = 3, 
entries => 
    0 : <CFString 0x101f47938 [0x10684e180]>{contents = "challenge"} = <NSURLAuthenticationChallenge: 0x7f98ec4cd700> 
    1 : <CFString 0x7f98e9fd03a0 [0x10684e180]>{contents = "Accept-Encoding"} = <CFBasicHash 0x7f98ec7c4490 [0x10684e180]>{type = mutable dict, count = 1, 
entries => 
    2 : <CFString 0x7f98ec78b930 [0x10684e180]>{contents = "Accept-Encoding"} = <CFString 0x106330828 [0x10684e180]>{contents = "gzip, deflate"} 
} 

    2 : <CFString 0x1063310e8 [0x10684e180]>{contents = "kCFURLRequestAllowAllPOSTCaching"} = <CFBoolean 0x10684ebf0 [0x10684e180]>{value = true} 
} 

このメッセージから、私はプロパティリストでサポートされているオブジェクトは、このAPIを使用してNSURLRequestに関連付けられます。しかし、なぜ私は完全に理解していない。

また、私の質問は、このAPIをどのような目的で使用するのかです。それを正しく使うには?私はちょうどsetProperty:forKey:inRequest:が何をしているか知りたいのですが、それは単にオブジェクトを要求に関連付けるよりも多くの作業をするようです。

UPDしたがって、最小限の検証可能な例。非常にシンプルなNSURLProtocolサブクラス:今のところ

#import "MyURLProtocol.h" 

#define kOurRecursiveRequestFlagProperty @"recursive" 

@interface MyURLProtocol() 
@property NSURLConnection *connection; 
@end 

@implementation MyURLProtocol 

+ (BOOL)canInitWithRequest:(NSURLRequest *)request { 
    return ![[[self class] propertyForKey:kOurRecursiveRequestFlagProperty inRequest:request] boolValue]; 
} 

- (id)initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)cachedResponse client:(id <NSURLProtocolClient>)client { 
    return [super initWithRequest:request cachedResponse:cachedResponse client:client]; 
} 

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request { 
    return request; 
} 

- (void)startLoading { 
    NSMutableURLRequest* mutableRequest = [[self request] mutableCopy]; 
    [[self class] setProperty:@YES forKey:kOurRecursiveRequestFlagProperty inRequest:mutableRequest]; 
    // Associate any non-property list object with mutableRequest to reproduce issue. 
    [[self class] setProperty:[UIApplication sharedApplication] forKey:@"dummyKey" inRequest:mutableRequest]; 
    self.connection = [[NSURLConnection alloc] initWithRequest:mutableRequest delegate:self startImmediately:YES]; 
} 

- (void)stopLoading { 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    [[self client] URLProtocolDidFinishLoading:self]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    [[self client] URLProtocol:self didLoadData:data]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; 
} 

- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse { 
    return request; 
} 

@end 

UPD2、私はキャッシュのせいであることがわかります。 NSURLCacheStorageNotAllowedを使用しても、このコードではキャッシュ辞書を作成し、その中に[UIApplication sharedApplication]を書き込むよう試みます。

2016年3月20日20:52:19.630 WebViewDemo [7102:663895] ADD:パス= /ユーザ/ XXX /ライブラリ/開発/ CoreSimulator /デバイス/ 89D7C50F-939B-4360でキャッシュ辞書の作成に失敗しました-A19F-4547AE4F7515/data /コンテナ/データ/アプリケーション/ 6F05411C-0261-4A33-9531-9E4E900C4910 /ライブラリ/キャッシュ/ Test.WebViewDemo。キー= 0x7fe76af45f90

次に、私の質問は次のとおりです。どうすればこの独自の関連辞書を実装せずにこのキャッシュを無効にできますか。私はそれをしなければならない、または私は単にsetProperty:forKey:inRequest:を避けるべきです。

そして、最も重要なのは、kOurRecursiveRequestFlagPropertyを保存するにはsetProperty:forKey:inRequest:を使用するのが正しいことです。Apple sampleはそれを示唆していますか?私はまだこの方法をいつ使うことができるのか、できないのかを理解しようとしています。

+0

解決しなければならない問題はありますか? SOは、アップルのエンジニアの思考プロセスに関する推測の場ではありません。 – Avi

+1

@Avi、私はコードの特定の問題を解決しようとはしていません。むしろ私が書いた**コードが何を理解しようとしていますか?「Appleエンジニアの考え」も面白い話題ですが、私の質問はそれらに関するものではありません。私は特定の方法のフードの下で何が起こるのか正確に尋ねます。**なぜそれらのメソッドを使用しようとすると予期しないエラーが発生するのですか?良い質問に関するFAQとメタの話し合いを二重チェックした後も、私の質問を不適切なものとみなす理由は見られません。たぶん、あなたは私に対応するトピックを指すことができますか? –

+0

結局のところ、FoundationのソースにアクセスできるAppleのエンジニアがいない限り、この質問は推測を生成するに過ぎません。したがって、それはSOには適切ではありません。 – Avi

答えて

2

IIRCの場合、データがplist-serializableでなければならない理由は、バックグラウンドタスクでは、URL要求がシリアル化され、実際にURLフェッチを実行するバックグラウンドデーモンに送られます。データがシリアライズ可能でない場合は、転送中に失われます。

ここに保存するオブジェクトは、プロトコルにを指定するために、プロトコルをに許可する目的で、小さな自己完結型のデータである必要があります。

通常、要求とより複雑なものを関連付ける必要がある場合は、このメソッドを使用してUUIDまたはその他の任意の文字列を格納します。次に、アプリケーション内の通常のNSDictionaryのキーと同じ文字列を保存し、クライアントに要求が完了した/失敗したことを伝えた後に、辞書キーと関連データを破棄します。

関連する問題