nmoschkin / MAUIWebViewExample

MAUI Custom Renderer For Hybrid Web View
MIT License
55 stars 17 forks source link

Please Extend your Code for the Windows Plattform #1

Open mahop-net opened 2 years ago

mahop-net commented 2 years ago

Great job - works great!!! I tried the same for windows but I can not find a function like AddUserScript() and CoreWebView2.AddHostObjectToScript(...) throws the error: 'The group or resource is not in the correct state to perform the requested operation.'

Could you PLEASE extend you example for Windows?

mahop-net commented 2 years ago

@nmoschkin You asked me to send you my code for windows. I will clean it up and post it here tomorrow morning. (Today I'm filled up with events and my youngest son has his birthday party this afternoon...)

mahop-net commented 2 years ago

First: I tried to find solutions mainly here:

Than I tried to use the funtion AddHostObjectToScript, AddScriptToExecuteOnDocumentCreatedAsync, Eval in code behind - in all different version and places - but without luck. The Code I tried is basically this one: (I tried it also on events like HandlerChanged and so on)

    public MainPage() {
        InitializeComponent();

        Dispatcher.DispatchDelayed(TimeSpan.FromSeconds(1), async () => {
            var view = MyWebView.Handler.PlatformView as Microsoft.Maui.Platform.MauiWebView;
            await view.EnsureCoreWebView2Async();
            view.CoreWebView2.AddHostObjectToScript("jsBridge", new JsBridge());

            //Try to call the JsBridge
            await view.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("console.log( chrome.webview.hostObjects.jsBridge.Func('xxx'));");
            //Or with this
            MyWebView.Eval("console.log( chrome.webview.hostObjects.jsBridge.Func('xxx')); ");
        });
    }

  [ClassInterface(ClassInterfaceType.AutoDual)]
  [ComVisible(true)]
  public class JsBridge {

      public string Func(string param) {
          return "Example: " + param;
      }
  }

And finally I tried to create a handler for the Windows plattform like in your code. But this is not even starting up but throws an error right at the beginning.

namespace MauiWebViewHostTester.Platforms.Windows.Handlers {
    public class HybridWebViewHandler : ViewHandler<IHybridWebView, Microsoft.Maui.Platform.MauiWebView> {
        public static PropertyMapper<IHybridWebView, HybridWebViewHandler> HybridWebViewMapper = new PropertyMapper<IHybridWebView, HybridWebViewHandler>(ViewHandler.ViewMapper);

        const string JavascriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";

        public HybridWebViewHandler() : base(HybridWebViewMapper) {
        }

        private void VirtualView_SourceChanged(object sender, SourceChangedEventArgs e) {
            LoadSource(e.Source, PlatformView);
        }

        protected override Microsoft.Maui.Platform.MauiWebView CreatePlatformView() {
            //TODO: Add JsBridge and JS Code here...
            return new Microsoft.Maui.Platform.MauiWebView();
        }

        protected override void ConnectHandler(Microsoft.Maui.Platform.MauiWebView platformView) {
            base.ConnectHandler(platformView);

            if (VirtualView.Source != null) {
                LoadSource(VirtualView.Source, PlatformView);
            }

            VirtualView.SourceChanged += VirtualView_SourceChanged;
        }

        protected override void DisconnectHandler(Microsoft.Maui.Platform.MauiWebView platformView) {
            base.DisconnectHandler(platformView);

            VirtualView.SourceChanged -= VirtualView_SourceChanged;
            VirtualView.Cleanup();
        }

        private static void LoadSource(WebViewSource source, Microsoft.Maui.Platform.MauiWebView control) {
            try {
                if (source is HtmlWebViewSource html) {
                    control.LoadHtml(html.Html, html.BaseUrl);
                } else if (source is UrlWebViewSource url) {
                    control.LoadUrl(url.Url);
                }
            } catch { }
        }
    }
}

My little testproject is attached. MauiWebViewHostTester.zip :

nmoschkin commented 2 years ago

Okay. I will take a look at this. I actually love WinUI 3. But it's unfortunate they've made it as somewhat separate piece from MAUI. I think MAUI is for more designing the cross platform experience. WinUI 3, on the other hand, has much more Windows-specific features and user experiences... it works better with native interop, it can compile in C++, etc. etc.

I will take a look at what you've got here and see if I can tinker with it.

Can I ask. Do you want the solution for MAUI, or do you want it for WinUI 3, or both?

mahop-net commented 2 years ago

I would like to get it working for Maui. My goal is: UI with JS and everything else with C# => Same Code on every (important) plattform. (Browser, Windows, Android, iOS)

Thank you very much for investing time on this!!!

mahop-net commented 2 years ago

Hello Nathaniel, we should keep the conversation here. As far as I know, stackoverflow does not want a conversation in the comments...

AND there ist absolutely no time pressure!!! Right now I'm working with the Xamarin Hybrid Web View and CefSharp (https://github.com/cefsharp/CefSharp) for Windows. But I would like to switch to Maui in the future and (if possible) have everything in Maui... So my timeplan is to check the posibilities during the next months and than switch my projects from Xamarin to Maui around the Ende of this year ( - if technically possible...)

nmoschkin commented 2 years ago

Alright, I will be touching base back here within the week. As I have now had even more thrown on top of me, I will probably only be able to find time on the weekend to deal with this. Thank you for your understanding.

nmoschkin commented 2 years ago

Sorry time got ahead of me. I will have time this weekend to fiddle with this code, though.

nmoschkin commented 2 years ago

Reading this code, I recently discovered that sometimes you need to add a 1 second delay to load correctly in Android code, too... and I'm going to get to the bottom of why this is for a work project, so I will definitely want to solve this, here, too.

nmoschkin commented 2 years ago

I finally got around to attempting to solve this...

It's not currently solvable, as the information relayed in posts from Microsoft indicates it's in the backlog to allow MAUI Windows projects to use the scripting host.

mahop-net commented 2 years ago

OK - thanks you for this info and thank you very much for spending time on this!!!

nmoschkin commented 2 years ago

Sure, no problem!

nmoschkin commented 2 years ago

I have written a work-around to the Windows problem. See the code and also the StackOverflow:

https://stackoverflow.com/questions/73217992/js-net-interact-on-maui-webview/73311704#73311704

nmoschkin commented 2 years ago

Note: Both Windows support and EvaluateJavaScriptAsync support are in the windows-maui-support branch and will be merged, soon.

nmoschkin commented 2 years ago

@Hopfenspirger have you had a chance to review this, yet?

mahop-net commented 1 year ago

@nmoschkin Sorry for the late answer! I was playing around with your code, and first it looked all very good, but than I discovered, that with the new Handler the WebView behaved differntly when loading local resources, like .html or .js files from Resources/Raw folder... I spend some time to fix this but without luck.

Than I was thinking a little bit in a different way and created a testproject. This is not really using any advanced connection between JS and C# but it is working for me and it is using the native Maui WebView like it is. So it's working for all Maui platforms.

I put the little project online on github. https://github.com/mahop-net/Maui.HybridWebView