I want to be able to send some extra headers with my UIWebView loadRequest
method.
I have tried:
NSMutableURLRequest *req = [NSMutableUR
The answer by Thomas will not work for (most of the) webpages with multiple iFrames. The solution will load an iFrame request over the full UIWebView. E.g. in case it calls loadRequest for a Google advt. (which is in some small iFrame) the advt. is loaded all over the UIWebView & nothing else.
I found that this was the way to add headers to my UIWebView request - override this delegate method:
- (BOOL) webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType) navigationType
With this code:
BOOL headerIsPresent = [[request allHTTPHeaderFields] objectForKey:@"my custom header"]!=nil;
if(headerIsPresent) return YES;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
NSURL *url = [request URL];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
// set the new headers
for(NSString *key in [self.customHeaders allKeys]){
[request addValue:[self.customHeaders objectForKey:key] forHTTPHeaderField:key];
}
// reload the request
[self loadRequest:request];
});
});
return NO;
Here is a complete implementation using NSURLProticol. You can put this code anywhere you like (e.i. its own or add to existing source file) and it should work. The two key methods to customize are canInitWithRequest:
and canonicalRequestForRequest:
.
static NSString * const NSURLProtocolHandledKey = @"NSURLProtocolHandledKey";
@interface WTCURLProtocol : NSURLProtocol<NSURLSessionDelegate>
@property (atomic,strong,readwrite) NSURLSessionDataTask *task;
@property (nonatomic,strong) NSURLSession *session;
@end
@implementation WTCURLProtocol
+(void)load
{
[NSURLProtocol registerClass:self];
}
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
// customize here by returning true for URLs that you want to handle
return [request.URL.absoluteString hasPrefix:WEB_BASE_URL];
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
NSMutableURLRequest *newRequest = request.mutableCopy;
[NSURLProtocol setProperty:@YES forKey:NSURLProtocolHandledKey inRequest:newRequest];
// customize here by setting your custom headers
[newRequest setValue:@"ABCDEFGHIJKLMNOPQRSTUVWXYZ" forHTTPHeaderField:@"API-TOKEN"];
return newRequest;
}
- (void)startLoading
{
NSURLSessionConfiguration *configure = [NSURLSessionConfiguration defaultSessionConfiguration];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
self.session = [NSURLSession sessionWithConfiguration:configure delegate:self delegateQueue:queue];
self.task = [self.session dataTaskWithRequest:self.request];
[self.task resume];
}
- (void)stopLoading
{
[self.session invalidateAndCancel];
self.session = nil;
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
if (error != nil) {
[self.client URLProtocol:self didFailWithError:error];
}else
{
[self.client URLProtocolDidFinishLoading:self];
}
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
{
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
completionHandler(NSURLSessionResponseAllow);
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
[self.client URLProtocol:self didLoadData:data];
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask willCacheResponse:(NSCachedURLResponse *)proposedResponse completionHandler:(void (^)(NSCachedURLResponse * _Nullable))completionHandler
{
completionHandler(proposedResponse);
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)newRequest completionHandler:(void (^)(NSURLRequest *))completionHandler
{
NSMutableURLRequest *redirectRequest = [newRequest mutableCopy];
[[self class] removePropertyForKey:NSURLProtocolHandledKey inRequest:redirectRequest];
[[self client] URLProtocol:self wasRedirectedToRequest:redirectRequest redirectResponse:response];
[self.task cancel];
[[self client] URLProtocol:self didFailWithError:[NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil]];
}
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
{
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
NSURLCredential *card = [[NSURLCredential alloc] initWithTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential,card);
}
}
@end
I find another way, Can use NSURLProtocol
.
-(BOOL)webView:(IMYVKWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSMutableDictionary* mapObject = [NSMutableDictionary dictionary];
mapObject[@"headers"] = request.allHTTPHeaderFields;
mapObject[@"navigationType"] = @(navigationType);
[webViewRequestMap setObject:mapObject forKey:request.URL.absoluteString];
return YES;
}
webViewRequestMap
is Static NSMutableDictionary*
in Your Custom NSURLProtocol code:
@interface IMYCustomURLProtocol : NSURLProtocol
@end
@implementation IMYCustomURLProtocol
+(void)load
{
[NSURLProtocol registerClass:self];
}
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
NSString* urlString = request.URL.absoluteString;
NSDictionary* dictionary = webViewReuqestMap[urlString];
if (dictionary)
{
[webViewRequestMap removeObjectForKey:urlString];
if ([request isKindOfClass:[NSMutableURLRequest class]]) {
[(id)request setValue:@"HAHA" forHTTPHeaderField:@"MeiYou Co.,Ltd"];
}
}
return NO;
}
@end