UIWebView - Safari 中的强制导航

Posted

技术标签:

【中文标题】UIWebView - Safari 中的强制导航【英文标题】:UIWebView - force navigation in safari 【发布时间】:2017-04-11 12:15:23 【问题描述】:

我在 Objective-c 中有一个 UIWebView,它加载带有嵌入视频的外部 html(我无权访问此 HTML)。此视频包含来自 Google Ads 的前贴片广告(但将来可能来自其他提供商)。 此广告有一个指向用户可以点击的外部网站的链接,但它似乎是由 javascript 事件(不是常规锚点)触发的。

我已设置委托以强制在 webview 中单击的链接在 Safari 中打开,但来自广告的这些链接继续在 webview 中打开。我认为这是因为它们是由 javascript 触发的。

这是我的代表:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:
(NSURLRequest *)request navigationType:
(UIWebViewNavigationType)navigationType

    if (navigationType == UIWebViewNavigationTypeLinkClicked) 
        [[UIApplication sharedApplication] openURL:[request URL]];
        return NO;
    
return YES;

有没有人知道一种方法可以强制在 webview 中加载的域之外的任何导航在 Safari 中打开?我想这样我可以绕过这个问题。

谢谢。

【问题讨论】:

【参考方案1】:

假设您提前知道“内部”域,您可以强制所有外部域在 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;

更新:

根据您的 cmets,如果以上还不够,您可以添加 UITapGestureRecognizer 来检测用户输入:

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)];
tapGesture.numberOfTouchesRequired = 1;
tapGesture.numberOfTapsRequired = 1;
tapGesture.delegate = self;
[self.webView addGestureRecognizer:tapGesture];

实现委托方法以确保您的点击被识别:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
    return YES;

在您的-tapGesture: 方法中,您可以设置一个临时的BOOL

-(void)tapGesture:(UITapGestureRecognizer *)tapGesture 
    self.userDidTap = YES;

然后在随后的-webView:shouldStartLoadWithRequest:navigationType: 方法中,您可以检查self.userDidTap 的值并采取相应措施:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 

    if (self.userDidTap) 
        [[UIApplication sharedApplication] openURL:[request URL]];
        return NO;
    

    return YES;

【讨论】:

我也想过这个,但是webview中加载的URL是通过api调用提供给应用程序的,并且可以一直不同。有没有办法知道点击请求时应用程序中加载的实际域,以便知道它是否不同? 您能否将从 API 接收到的初始 URL 存储为属性,并将该主机(NSURL -host 方法)与 [request URL] 中的主机进行比较? 我想我可以,但是加载的 webviews 的数量是未知的。我调用了一个 api,该 api 可以返回一个 URL 以加载到 webview 中,或者许多......所有可能都有不同的 URL...... 明白。我已经用替代解决方案更新了我的答案。希望有帮助! 我现在无法测试,但看起来很有希望!谢谢!

以上是关于UIWebView - Safari 中的强制导航的主要内容,如果未能解决你的问题,请参考以下文章

UIWebView在Safari中打开链接

如何强制显示移动 Safari 底部导航栏以编程方式显示?

Safari 中的 UIWebView 打开链接不起作用?

通过 UIWebView 从网页打开 Safari 中的链接

如何从 UIWebView 打开 safari.app 中的外部链接?

与 Safari/Chrome 相比,相同 URL 的 UIWebView 行为不同