I have a UIWebView in objective-c that loads an external HTML with an embedded video (I have no access to this HTML). This video has a pre-roll ad from Google Ads (but can be from another provider in the future). This ad has a link to an external website that the user can click but it seems to be triggered by a javascript event (not a regular anchor).
I have set the delegate in order to force clicked links in the webview to open in Safari, but these links from the ads keep opening inside the webview. I think it's because they are triggered from javascript.
This is my delegate:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:
(NSURLRequest *)request navigationType:
(UIWebViewNavigationType)navigationType
{
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}
return YES;
}
Does anyone knows of a way to force any navigation outside the domain loaded in the webview to open in Safari? I guess this way I could circumvent this problem.
Thanks.
Assuming you know the "internal" domain ahead of time, you could force all external domains to open in Safari:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (![request.url.absoluteString containsString:@"https://www.yourinternaldomain.com"]) {
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}
return YES;
}
Update:
Based on your comments, if the above won't suffice, you could add a UITapGestureRecognizer
to detect user input:
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)];
tapGesture.numberOfTouchesRequired = 1;
tapGesture.numberOfTapsRequired = 1;
tapGesture.delegate = self;
[self.webView addGestureRecognizer:tapGesture];
Implement the delegate methods to ensure your tap is recognised:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
In your -tapGesture:
method, you can then set a temporary BOOL
:
-(void)tapGesture:(UITapGestureRecognizer *)tapGesture {
self.userDidTap = YES;
}
And then in the subsequent -webView:shouldStartLoadWithRequest:navigationType:
method, you can inspect the self.userDidTap
value and act accordingly:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (self.userDidTap) {
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}
return YES;
}