コード例 #1
0
        private Task <InteropHandshakeResult> AttachInteropAsync()
        {
            var resultTcs = new TaskCompletionSource <InteropHandshakeResult>();

            // These hacks can go away once there's a proper IPC channel for event notifications etc.
            var selfAsDotNetObjectReference = typeof(DotNetObjectReference).GetMethod(nameof(DotNetObjectReference.Create))
                                              .MakeGenericMethod(GetType())
                                              .Invoke(null, new[] { this });
            var selfAsDotnetObjectReferenceId = (long)typeof(JSRuntime).GetMethod("TrackObjectReference", BindingFlags.NonPublic | BindingFlags.Instance)
                                                .MakeGenericMethod(GetType())
                                                .Invoke(_jsRuntime, new[] { selfAsDotNetObjectReference });

            _ipc.Once("components:init", args =>
            {
                var argsArray          = (object[])args;
                var initialUriAbsolute = ((JsonElement)argsArray[0]).GetString();
                var baseUriAbsolute    = ((JsonElement)argsArray[1]).GetString();
                resultTcs.TrySetResult(new InteropHandshakeResult(baseUriAbsolute, initialUriAbsolute));
            });

            _ipc.On("BeginInvokeDotNetFromJS", args =>
            {
                var argsArray        = (object[])args;
                var assemblyName     = argsArray[1] != null ? ((JsonElement)argsArray[1]).GetString() : null;
                var methodIdentifier = ((JsonElement)argsArray[2]).GetString();
                var dotNetObjectId   = ((JsonElement)argsArray[3]).GetInt64();
                var callId           = ((JsonElement)argsArray[0]).GetString();
                var argsJson         = ((JsonElement)argsArray[4]).GetString();

                // As a temporary hack, intercept blazor.desktop.js's JS interop calls for event notifications,
                // and direct them to our own instance. This is to avoid needing a static BlazorHybridRenderer.Instance.
                // Similar temporary hack for navigation notifications
                // TODO: Change blazor.desktop.js to use a dedicated IPC call for these calls, not JS interop.
                if (assemblyName == "Microsoft.MobileBlazorBindings.WebView")
                {
                    assemblyName   = null;
                    dotNetObjectId = selfAsDotnetObjectReferenceId;
                }

                DotNetDispatcher.BeginInvokeDotNet(
                    _jsRuntime,
                    new DotNetInvocationInfo(assemblyName, methodIdentifier, dotNetObjectId, callId),
                    argsJson);
            });

            _ipc.On("EndInvokeJSFromDotNet", args =>
            {
                var argsArray = (object[])args;
                DotNetDispatcher.EndInvokeJS(
                    _jsRuntime,
                    ((JsonElement)argsArray[2]).GetString());
            });

            _webView.Source = new XF.UrlWebViewSource {
                Url = $"{BlazorAppScheme}://0.0.0.0/"
            };

            return(resultTcs.Task);
        }