My app uses subclassing of NSURLProtocol. There are several UIWebViews in the app and for specific algorithm implemented in NSURLProtocol I need to know which one of the UIWebViews sends the request.
My understanding is that object returned by [self client] should be somewhat connected with requesting object. But neither NSURLProtocolClient (that is the protocol implemented by object returned by [self client]) nor underlying object _NSCFURLProtocolBridge have any properties/methods to get the sender of the request.
Can anyone help me with ideas?
NSURLRequest
has a method called mainDocumentURL
which returns the URL of the root document. You can possibly save that away in the UIWebViewDelegate
method like this,
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if([[request.URL absoluteString] isEqualToString:[request.mainDocumentURL absoluteString]])
{
// associate this URL with this UIWebview
}
}
You can then look at the mainDocumentURL
in your NSURLProtocol
methods to identify the UIWebView
. This is not fool proof since it doesn't account for cases where multiple UIWebViews
load the same URL. But this is the best solution I could think of.
See https://stackoverflow.com/a/19700910/502149. To summarize, you can set the user agent for each UIWebView
before you create it using the user defaults. Because the view doesn't take subsequent changes of the user agent into account, you'll end up with a different user agent in each UIWebView
. You can use this in NSURLProtcol
to identify the view, and you can pass on the real UA agent so the server won't see any difference.
Note that for the UIWebView
to "remember" the UA string setting, it has to make at least one request before the setting is changed.
in loadRequest:
static NSString* ProtocolClient=@"urAPP_ProtocolClient";
NSMutableURLRequest* Request=[request mutableCopy];
[Request setValue:[NSString stringWithFormat:@"someID",self.someID] forHTTPHeaderField:ProtocolClient];
in protocol:
NSString* header=[_currentRequest valueForHTTPHeaderField:ProtocolClient];
if (header) {
- (BOOL)webView:(UIWebView *)aWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
Request is mutable type. So you can use
+[NSURLProtocol setProperty:forKey:inRequest:]
to set custom property.
And +[NSURLProtocol propertyForKey:inRequest]
from inside of NSURLProtocol
Ideally, you shouldn't have to reference the UIWebView directly from the NSURLProtocol. However, I have had need in the past to have an NSURLProtocol send messages to UIWebView that are outside of the regular delegate messages... use NSNotificationCenter, I post notifications using the NSURLRequest object as the object, and subscribe to those notifications on my interested listener.