【问题标题】:UIWebView Desktop Website Won't WorkUIWebView 桌面网站无法正常工作
【发布时间】:2016-09-14 03:52:40
【问题描述】:

部分是作为学习一点 iOS 编程的练习,部分是因为我希望我在 iPad 上有一个 WhatsApp 客户端,我正在尝试创建一个应用程序,我可以亲自将其用作我的 iPad 的 WhatsApp 客户端。它所做的只是在 UIWebView 中加载 web.whatsapp.com 桌面站点,如下所示:

override func viewDidLoad() {
    NSUserDefaults.standardUserDefaults().registerDefaults(["UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17"])
    super.viewDidLoad()

    self.webView.frame = self.view.bounds
    self.webView.scalesPageToFit = true

    // Do any additional setup after loading the view, typically from a nib.
    let url = NSURL(string: "https://web.whatsapp.com")
    let requestObj = NSMutableURLRequest(URL: url!)
    webView.loadRequest(requestObj)
    //webView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}

这工作正常。它实际上加载了正确的 webapp,而不是像服务器检测到移动设备时通常发生的那样重定向到 whatsapp 主页。但是,它不是向我显示用于登录的 QR 码屏幕,而是向我显示以下内容:

现在,如果我在 iPad 上使用 Safari 中的 WhatsApp Web(并请求桌面版本),它可以正常工作。如您所见,我通过设置 UserAgent 为我的 UIWebView 请求桌面站点。现在,我想知道为什么它在 UIWebView 中不起作用,以及是否可能需要设置其他标头或值才能说服应用程序在我的 UIWebView 控件中工作?

编辑

通过将 Boris Verebsky 的代码从 Objective-C 转换为 Swift,我已更改为 WKWebView。然而,虽然起初我看到的屏幕和以前一样(告诉我使用另一个浏览器),但在改变它并试图让它工作之后,我发现自己的屏幕是空白的。什么都没有出现了。

这是我目前的完整代码:

import UIKit
import WebKit

class ViewController: UIViewController, WKNavigationDelegate {

    @IBOutlet var webView: WKWebView!

    override func viewDidLoad() {

        super.viewDidLoad()
        self.webView = WKWebView(frame: self.view.bounds)

        if #available(iOS 9.0, *) {
            self.webView.customUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17"
        } else {
            // Fallback on earlier versions
            NSUserDefaults.standardUserDefaults().registerDefaults(["UserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/601.5.17 (KHTML, like Gecko) Version/9.1 Safari/601.5.17"])
        }
        self.view!.addSubview(self.webView)
        self.webView.navigationDelegate = self

        // Do any additional setup after loading the view, typically from a nib.
        let url: NSURL = NSURL(string: "http://web.whatsapp.com")!
        let urlRequest: NSURLRequest = NSURLRequest(URL: url)
        webView.loadRequest(urlRequest)
    }

    func webView(webView: WKWebView, decidePolicyForNavigationAction: WKNavigationAction, decisionHandler: WKNavigationActionPolicy -> Void) {
        decisionHandler(.Allow)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

可能是我从 Objective-C 到 Swift 的转换不正确。我不熟悉 Objective-C,所以很有可能。

【问题讨论】:

  • 您的代码是正确的。您有空白视图的原因是运输安全。要么使用 https://web.whatsapp.com 作为 URL(注意 HTTPS 而不是 HTTP),或者在你的应用程序 info.plist 中添加 NSAllowsArbitraryLoads: YES
  • @BorisVerebsky 谢谢,它现在可以工作了。在我完成之前,还有一些其他问题需要克服!
  • web.whatsapp.com 页面加载需要哪些权限
  • 我尝试但没有加载web.whatsapp.com页面请任何知道帮助我的人

标签: ios swift ipad uiwebview


【解决方案1】:

检查用户代理后,https://web.whatsapp.com 检查客户端是否支持 indexeddb,可能是通过一些 JavaScript。很容易注意到 - 如果您将跟踪您的应用程序执行的所有重定向,那么您会发现重定向到 https://web.whatsapp.com/browsers.html?missing=indexeddb。就我而言,我使用简单的NSURLProtocol 子类来记录所有重定向。遗憾的是,NSURLProtocol 不再适用于 WKWebView

UIWebView 根本没有实现 indexeddb。据我所知,自己实现 indexeddb 支持没有简单的方法。

您可以通过访问UIWebView 中的 html5test.com 轻松检查 indexeddb 支持。你会看到类似的东西:

WKWebView 确实支持 indexeddb:

我已经使用自定义用户代理检查了 iOS WKWebView 中的 web.whatsapp.com 加载,使用 http://whatsmyuseragent.com 从我的桌面 Safari 中获取,它显示了您预期的 QR 码。此外,迁移到 WKWebView 会带来一些好处,例如提高性能和稳定性。

我使用以下代码进行测试:

#import <WebKit/WebKit.h>

@interface ViewController () <WKNavigationDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
    self.webView.customUserAgent = @"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/601.6.17 (KHTML, like Gecko) Version/9.1.1 Safari/601.6.17";
    [self.view addSubview:self.webView];

    self.webView.navigationDelegate = self;

    NSURL *url = [NSURL URLWithString:@"http://web.whatsapp.com"];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:urlRequest];
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(nonnull WKNavigationAction *)navigationAction decisionHandler:(nonnull void (^)(WKNavigationActionPolicy))decisionHandler {
    decisionHandler(WKNavigationActionPolicyAllow);
}

@end

虽然是 Objective-C,但转换成 swift 应该很简单。

UPD:

WKWebView 出现空白视图的原因是传输安全性。要么使用 https://web.whatsapp.com 作为 URL(注意 HTTPS 而不是 HTTP),或者在你的应用程序 info.plist 中添加 NSAllowsArbitraryLoads: YES

【讨论】:

  • 我已经编辑了我的问题。我不确定我对 swift 的转换是否正确。我对Objective C不熟悉。你能看看吗?我现在看到一个空白屏幕。
  • @Boris 这是一个很好的解释.. 我在 android 中做同样的事情,你对此有什么想法
  • 在android中我尝试使用自定义用户代理,第一次webView加载二维码页面,第二次加载WhatsApp.com页面
  • 过去几周我尝试了很多但找不到解决方案
【解决方案2】:

你真的应该切换到使用WKWebView,然后你可以简单地使用customUserAgent在网络视图上直接设置你想要的代理字符串。

【讨论】:

  • 谢谢,我试试看!
  • 您的意思是未设置代理(使用 charles proxy 之类的工具进行验证)或网站仍然没有按照您的意愿行事?
  • 我的意思是,我已经设置了代理,但它仍然不起作用。现在,连网页都没有加载。
  • 您是否使用代理工具检查了请求中实际发送的代理是什么?如果您什么也没看到,则需要显示您使用过的代码。包括调用委托方法的详细信息
  • 你我已经用代理工具检查过了。可以这样吗,因为我正在创建一个 mac 应用程序。你有工作演示吗。如果有,你能和我分享一下吗?我的 ID 是 raviparmar213@gmail.com
猜你喜欢
  • 2018-02-17
  • 1970-01-01
  • 1970-01-01
  • 2016-03-15
  • 2017-12-03
  • 2018-10-13
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
相关资源
最近更新 更多