1

NSURLProtocol次のメソッドを定義します。

/*! 
    @method propertyForKey:inRequest:
    @abstract Returns the property in the given request previously
    stored with the given key.
    @discussion The purpose of this method is to provide an interface
    for protocol implementors to access protocol-specific information
    associated with NSURLRequest objects.
    @param key The string to use for the property lookup.
    @param request The request to use for the property lookup.
    @result The property stored with the given key, or nil if no property
    had previously been stored with the given key in the given request.
*/
+ (nullable id)propertyForKey:(NSString *)key inRequest:(NSURLRequest *)request;

/*! 
    @method setProperty:forKey:inRequest:
    @abstract Stores the given property in the given request using the
    given key.
    @discussion The purpose of this method is to provide an interface
    for protocol implementors to customize protocol-specific
    information associated with NSMutableURLRequest objects.
    @param value The property to store. 
    @param key The string to use for the property storage. 
    @param request The request in which to store the property. 
*/
+ (void)setProperty:(id)value forKey:(NSString *)key inRequest:(NSMutableURLRequest *)request;

/*!
    @method removePropertyForKey:inRequest:
    @abstract Remove any property stored under the given key
    @discussion Like setProperty:forKey:inRequest: above, the purpose of this
        method is to give protocol implementors the ability to store 
        protocol-specific information in an NSURLRequest
    @param key The key whose value should be removed
    @param request The request to be modified
*/
+ (void)removePropertyForKey:(NSString *)key inRequest:(NSMutableURLRequest *)request;

NSURLAuthenticationChallengeしかし、次のコードを使用して、リクエストに関連付けようとすると

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

ログに次のエラーが表示されます。

2016-03-20 18:00:41.252 Web@Work[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}
}

NSURLRequestこのメッセージから、プロパティ リストをサポートするオブジェクトのみがこの API の使用に関連付けられている可能性があると思われます。しかし、私はその理由を完全には理解していません。

また、私の質問は、この 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-03-20 20:52:19.630 WebViewDemo[7102:663895] 追加: path=/Users/xxx/Library/Developer/CoreSimulator/Devices/89D7C50F-939B-4360-A19F-4547AE4F7515/data でキャッシュ ディクショナリを作成できませんでした/コンテナ/データ/アプリケーション/6F05411C-0261-4A33-9531-9E4E900C4910/ライブラリ/キャッシュ/Test.WebViewDemo. キー=0x7fe76af45f90

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

そして、最も重要なことは、Apple のサンプルが示唆するように、それを store に使用するのは正しいですsetProperty:forKey:inRequest:? このメソッドをいつ使用できるか、いつ使用できないかをまだ理解しようとしています。kOurRecursiveRequestFlagProperty

4

1 に答える 1