0
votes

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.

1

1 Answers

0
votes

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;
}