【问题标题】:How to test IOS in use from the javascript inside a WKWebView on iPadOS 13如何从 iPadOS 13 上的 WKWebView 中的 javascript 测试正在使用的 IOS
【发布时间】:2020-02-17 19:37:43
【问题描述】:

当我使用 XCode 11.1 在“iPhone 8”模拟器中使用 WKWebView 测试我的混合应用程序并使用 Safari 13 检查 userAgent 时,我得到以下字符串:

"Mozilla/5.0 (iPhone; CPU iPhone OS 13_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148" 

但是,当我在“iPad Pro(11 英寸)”模拟器中测试应用程序时,我发现 userAgent 设置为以下字符串:

"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko)"

请注意,此字符串不包含子字符串“iPad”,也不包含正在使用的 IOS 版本,也不包含它是移动应用这一事实。

当我的应用程序检查 userAgent 以确定它是否在 IOS 下运行时,这在 iPhone 上运行良好,但给我带来了一个问题,即现在如何在运行 iPadOS 13 的 iPad 上运行此测试。请注意,这没什么与web view如何显示有关,就是javascript和Objective C之间是否建立通信。

我的应用在所有运行 IOS 12 的 iPad 上运行良好,因为 userAgent 符合我的预期:

"Mozilla/5.0 (iPad; CPU OS 12_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16B92"

我现在应该如何从 Javascript 内部确定我的代码是否在运行 iPadOS 13 或更高版本的 iPad 上运行?

【问题讨论】:

    标签: xcode ipad ios-simulator user-agent


    【解决方案1】:

    这不是任何类型的错误。这是一个非常好的功能,是 iOS 13 中的新功能。默认情况下,iPad 将自己呈现为桌面浏览器,而不是移动浏览器。

    【讨论】:

    • 与标题无关。我已经解释了为什么会发生这种情况以及如何了解更多信息。也请参见视频 518。
    • 请观看我推荐的视频。他们给你你的选择。我所做的就是回答这个问题。这是故意的。 iPad 浏览器,无论是 Safari 还是全屏 WKWebView,现在默认为 .desktop,这意味着它们将自己呈现为桌面浏览器,而不是移动浏览器。您可以为 WKWebView 或链接更改它。你可能不喜欢那个答案,但它仍然是答案。
    • 感谢我可以在 WKWebView 中覆盖 userAgent 的提示,但是我还找到了一种更快实现的不同方式,即代码中的更改更少。顺便说一句,我的问题与 Apple 决定将 Web 内容显示为台式机的决定无关,我已经这样做了 5 年。它是关于 webview 和 wrapper 之间的混合应用程序通信,并在我的代码内部确定我的代码是在 Android 还是 IOS 平台上运行。
    【解决方案2】:

    有很多方法可以解决这个问题。

    1. 根本不测试——加载后只是使用评估Javascript告诉webview它是IOS。

    2. 使用 Objective C/swift 检测 iPad 并在用户默认值中注册自定义用户代理字符串,其中包含字符串“iPad:在创建 Web 视图之前”

       // get original UserAgent string by using temporal webView
       WKWebView *tmp = [[WKWebView alloc] init];
       NSString *originalUA = [tmp stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
      
       // create custom UserAgent string
       NSString *customUA = [NSString stringWithFormat:@"%@ %@", originalUA, @" iPad"];
      
       // set custom UserAgent as default
       NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:customUA , @"UserAgent", nil];
       [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
      

    但是,也许出于错误的原因,我决定使用Missing iPad tablet Web traffic 的解决方案

    如下

    但它会错误地将新的 mac(带有 Apple m1 芯片)检测为 iPad。

    var agent = window.navigator.userAgent;
    var d=document;
    var e=d.documentElement;
    var g=d.getElementsByTagName('body')[0];
    var deviceWidth=window.innerWidth||e.clientWidth||g.clientWidth;
    
    // Chrome
    var IsChromeApp = window.chrome && chrome.app && chrome.app.runtime;
    
    // iPhone
    var IsIPhone = agent.match (/iPhone/i) != null;
    
    // iPad up to IOS12
    var IsIPad = (agent.match (/iPad/i) != null) || ((agent.match(/iPhone/i) != null) && (deviceWidth > 750)); // iPadPro when run with no launch screen can have error in userAgent reporting as an iPhone rather than an iPad. iPadPro width portrait 768, iPhone6 plus 414x736 but would probably always report 414 on app startup
    
    if (IsIPad) IsIPhone = false ;
    
    // iPad from IOS13
    var macApp = agent.match (/Macintosh/i) != null; 
    if (macApp)
        {
        // need to distinguish between Macbook and iPad
        var canvas = document.createElement ("canvas");
        if (canvas != null) 
            {
            var context = canvas.getContext ("webgl") || canvas.getContext ("experimental-webgl");
            if (context) 
                {
                var info = context.getExtension ("WEBGL_debug_renderer_info");
                if (info) 
                    {
                    var renderer = context.getParameter (info.UNMASKED_RENDERER_WEBGL);
                    if (renderer.indexOf ("Apple") != -1) IsIPad = true ; 
                    };
                };
            };
        };
        
    // IOS            
    var IsIOSApp = IsIPad || IsIPhone ;
    
    // Android
    var IsAndroid = agent.match (/Android/i) != null; 
    var IsAndroidPhone = IsAndroid && deviceWidth <= 960 ;
    var IsAndroidTablet = IsAndroid && !IsAndroidPhone ;
    

    【讨论】:

      猜你喜欢
      • 2020-02-25
      • 1970-01-01
      • 1970-01-01
      • 2019-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      相关资源
      最近更新 更多