Xamarin iOS HybridWebView不执行iOS 15>iPad的JavaScript文件

iyfjxgzm  于 2022-12-07  发布在  iOS
关注(0)|答案(1)|浏览(186)

我正在开发一个跨平台应用程序,该应用程序具有HybridWebView并显示本地html文件。我有一个wwwroot文件夹,其中包含html文件、css文件、js文件和所有其他资源。我已将完整文件夹构建为BundleResource。我还使用EmbedIO启动了一个本地Web服务器。当我在iPad上启动该应用程序时(iOS 15〉),它不执行JavaScript文件。在iPhone(iOS 15〉)上,该应用程序工作正常。同样在iOS 12的iPad上,该应用程序工作正常。此外,无论使用什么设备,该应用程序都可以在Safari上工作。
我已经在info.plist中添加了NSAppTransportSecurity和NSAAllowsArbitraryLoads = true。另外,我开发了一个带有WebView的Swift应用程序,并尝试使用Xamarin.iOS应用程序的本地Web服务器来显示应用程序。但是JavaScript同样没有执行(我还设置了关于JavaScript的首选项)。

    • 我的问题:**

我不明白为什么这个应用程序在Safari、iPhone和旧iPad上都能用,但在新iPad上却不行。我怀疑你必须启用JavaScript,但找不到相应的解决方案。

    • 值得一提的是:**

我只在index.html中加载一个js文件,这个js文件依次加载其他js文件(如上所述,除了新的iPad之外,这在所有设备上都有效)。
下面我添加了混合网络视图. cs、混合网络视图渲染器. cs、主页. xaml.cs和主页. xaml。

    • 主页面. xaml:**
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:d="http://xamarin.com/schemas/2014/forms/design"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:extensions="clr-namespace:Viewer.Extensions;assembly=Viewer"
    x:Class="Viewer.MainPage">

    <StackLayout>
        <extensions:HybridWebView x:Name="HybridWebView" Uri="{Binding WebViewSource}" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" />
    </StackLayout>

</ContentPage>
    • 主页面. xaml. cs:**
namespace Viewer
{
    [DesignTimeVisible(false)]
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class MainPage : ContentPage
    {
        private readonly LocalWebServer _server = new LocalWebServer();

        private string _webViewSource;
        public string WebViewSource
        {
            get => _webViewSource;
            set
            {
                _webViewSource = value;
                OnPropertyChanged(nameof(WebViewSource));
            }
        }

        public MainPage()
        {
            InitializeComponent();
            BindingContext = this;

            NavigationPage.SetHasNavigationBar(this, false);
            HybridWebView.RegisterAction(data =>
            {
                DisplayAlert("Alert", "Hello " + data, "OK");
            });
            HybridWebView.RegisterQRAction(() =>
            {
                try
                {
                    ZXingScannerPage scanPage = new ZXingScannerPage();
                    scanPage.OnScanResult += (result) =>
                    {
                        scanPage.IsScanning = false;

                        Device.BeginInvokeOnMainThread(async () =>
                        {
                            await Navigation.PopAsync();

                            var barcode = result.Text.ParseBarcode();
                            switch (barcode.BarcodeType)
                            {
                                case BarcodeType.Hotspot:
                                    {
                                        await HybridWebView.EvaluateJavaScriptAsync(
                                            $"javascript:doLoadHS('{barcode.Datamodule}.html', '{barcode.Hotspot.figureId}', '{barcode.Hotspot.hotspotId}');");
                                        break;
                                    }
                                case BarcodeType.Datamodule:
                                default:
                                    {
                                        await HybridWebView.EvaluateJavaScriptAsync(
                                            $"javascript:doLoad('{barcode.Datamodule}.html');");
                                        break;
                                    }
                            }
                        });
                    };

                    Device.BeginInvokeOnMainThread(() =>
                    {
                        Navigation.PushAsync(scanPage);
                    });
                }
                catch (Exception ex)
                {
                    DisplayAlert("QR", $"Error while reading qr code: {ex.Message}", "OK");
                }
            });
            HybridWebView.RegisterProjectSelectionAction(() =>
            {
                _server.Dispose();
                Navigation.PopToRootAsync();
            });

            var docpath = Helper.PathAddBackslash(Path.Combine(DependencyService.Get<IApplicationConfigurationService>().DocumentationRootPath, Init.NAME_DIR_WWWROOT));        

            _server.StartWebServer(docpath, false, false);

            WebViewSource = $"{LocalWebServer.Url}/index.html";
            
            NavigationPage.SetHasBackButton(this, false);
        }
        protected override bool OnBackButtonPressed()
        {
            return true;
        }
    }
}
    • 混合网络视图. cs:**
using System;
using Xamarin.Forms;

namespace Viewer.Extensions
{
    public class HybridWebView : WebView
    {
        Action<string> action;
        Action qrAction;
        Action projectSelectionAction;

        public static readonly BindableProperty UriProperty = BindableProperty.Create(
            propertyName: "Uri",
            returnType: typeof(string),
            declaringType: typeof(HybridWebView),
            defaultValue: default(string));

        public string Uri
        {
            get { return (string)GetValue(UriProperty); }
            set { SetValue(UriProperty, value); }
        }

        public void RegisterAction(Action<string> callback)
        {
            action = callback;
        }

        public void RegisterQRAction(Action callback)
        {
            qrAction = callback;
        }
        public void RegisterProjectSelectionAction(Action callback)
        {
            projectSelectionAction = callback;
        }

        public void Cleanup()
        {
            action = null;
            qrAction = null;
            projectSelectionAction = null;
        }

        public void InvokeAction(string data)
        {
            if (action == null || data == null)
            {
                return;
            }
            action.Invoke(data);
        }

        public void InvokeQRAction()
        {
            qrAction?.Invoke();
        }

        public void InvokeProjectSelectionAction()
        {
            projectSelectionAction?.Invoke();
        }
    }
}
    • 混合网络视图呈现器. cs:**
[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
namespace Viewer.iOS.Views
{
    public class HybridWebViewRenderer : WkWebViewRenderer, IWKScriptMessageHandler
    {
        const string JavaScriptFunction = "function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}" +
                                            "function invokeCSharpQRAction(data){window.webkit.messageHandlers.invokeQRAction.postMessage(data);}";

        WKUserContentController userController;

        public HybridWebViewRenderer() : this(new WKWebViewConfiguration())
        {
        }

        public HybridWebViewRenderer(WKWebViewConfiguration config) : base(config)
        {
            userController = config.UserContentController;
            var script = new WKUserScript(new NSString(JavaScriptFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
            userController.AddUserScript(script);
            userController.AddScriptMessageHandler(this, "invokeAction");
            userController.AddScriptMessageHandler(this, "invokeQRAction");
        }

        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                userController.RemoveAllUserScripts();
                userController.RemoveScriptMessageHandler("invokeAction");
                userController.RemoveScriptMessageHandler("invokeQRAction");
                HybridWebView hybridWebView = e.OldElement as HybridWebView;
                hybridWebView.Cleanup();
            }

            if (e.NewElement != null)
            {
                LoadRequest(new NSUrlRequest(new NSUrl(((HybridWebView)Element).Uri)));
            }

        }

        public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
        {
            var eventArgs = message.Body.ToString().ParseEventArgs();
            switch (eventArgs.name)
            {
                case "invokeAction":
                    ((HybridWebView)Element).InvokeAction(eventArgs.payload);
                    break;
                case "invokeQRAction":
                    ((HybridWebView)Element).InvokeQRAction();
                    break;
            }
        }
    }
}
kokeuurv

kokeuurv1#

这里的问题可能与您的Javascript有关。
移动的设备和较旧的设备通常会抑制Javascript的控制台错误,而不是错误页面或异常,进一步的Javascript不执行,看起来好像根本没有执行。
特别是对于有许多用法和引用的复杂Javascript,如果一个引用有问题就足够了,所以你什么也看不到。
在这里,它可以帮助简化Javascript,并一点一点地重建它以定位错误。

相关问题