Xcode 如何在iPadOS 13上通过WKWebView中的javascript测试正在使用的IOS

Xcode 如何在iPadOS 13上通过WKWebView中的javascript测试正在使用的IOS,xcode,ipad,ios-simulator,user-agent,Xcode,Ipad,Ios Simulator,User Agent,当我使用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" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) App

当我使用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" 
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko)"
然而,当我在“iPad Pro(11英寸)”模拟器中测试应用程序时,我发现userAgent设置为以下字符串:

"Mozilla/5.0 (iPhone; CPU iPhone OS 13_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148" 
"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视图的显示方式无关,而是与是否在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上运行?

这不是任何类型的错误。这是一个非常好的特性,在iOS 13中是新的。默认情况下,iPad是桌面浏览器,而不是移动浏览器

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

  • 根本不进行测试,只是在加载后使用evaluateJavascript告诉webview它是IOS

  • 使用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];
    
  • 然而,也许是出于错误的原因,我决定使用

    如下

    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
    IsChromeApp = window.chrome && chrome.app && chrome.app.runtime;
    
    // iPhone
    IsIPhone = agent.match (/iPhone/i) != null;
    
    // iPad up to IOS12
    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            
    IsIOSApp = IsIPad || IsIPhone ;
    
    // Android
    IsAndroid = agent.match (/Android/i) != null; 
    IsAndroidPhone = IsAndroid && deviceWidth <= 960 ;
    IsAndroidTablet = IsAndroid && !IsAndroidPhone ;
    
    var-agent=window.navigator.userAgent;
    var d=文件;
    var e=d.documentElement;
    var g=d.getElementsByTagName('body')[0];
    var deviceWidth=window.innerWidth | | e.clientWidth | | g.clientWidth;
    //铬
    IsChromeApp=window.chrome&&chrome.app&&chrome.app.runtime;
    //iPhone
    IsIPhone=agent.match(/iPhone/i)!=null;
    //iPad到IOS12
    IsIPad=(agent.match(/iPad/i)!=null)|((agent.match(/iPhone/i)!=null)&&(deviceWidth>750))//iPadPro在没有启动屏幕的情况下运行时,用户代理报告为iPhone而不是iPad时可能会出现错误。iPadPro宽度为768,iPhone6加414x736,但在应用程序启动时可能总是报告414
    如果(IsIPad)IsIPhone=false;
    //IOS13的iPad
    var macApp=agent.match(/Macintosh/i)!=null;
    if(macApp)
    {
    //需要区分Macbook和iPad
    var canvas=document.createElement(“画布”);
    if(canvas!=null)
    {
    var context=canvas.getContext(“webgl”)| canvas.getContext(“实验性webgl”);
    如果(上下文)
    {
    var info=context.getExtension(“WEBGL_调试_渲染器_信息”);
    如果(信息)
    {
    var renderer=context.getParameter(info.UNMASKED_renderer_WEBGL);
    如果(renderer.indexOf(“苹果”)!=-1)IsIPad=true;
    };
    };
    };
    };
    //IOS
    IsIOSApp=IsIPad | | IsIPhone;
    //安卓
    IsAndroid=agent.match(/Android/i)!=null;
    
    IsAndroidPhone=IsAndroid&&deviceWidth请观看与标题无关的内容。我已经解释了发生这种情况的原因以及如何了解更多信息。请参阅视频518。请观看我建议的视频。它们为您提供了选项。我所做的是回答问题。这是经过深思熟虑的。iPad浏览器,无论是Safari还是全屏WKWebV查看,默认情况下现在是
    .desktop
    ,这意味着它们将自己呈现为桌面浏览器,而不是移动浏览器。您可以为WKWebView或链接更改这一点。您可能不喜欢这个答案,但它仍然是答案。感谢您提示我可以覆盖WKWebView中的userAgent,但是我也找到了一种更快的方法o实现,即减少代码的更改。顺便提一下,我的问题与苹果决定将web内容显示为台式机无关,我已经做了5年了。这是关于webview和包装器之间的混合应用程序通信,并在我的代码中确定我的代码是在Android还是在IOS平台上运行。