У меня есть приложение Xamarin Forms, которые необходимо вызвать веб-страницу, которая содержит пользовательскую карту Bing и на веб-странице, она должна иметь возможность получить текущее местоположение пользователей.
Приложение уже имеет необходимые разрешения «приложения» для Android и iOS, и я могу получить местоположение пользователя внутри приложения без проблем.
Когда я называю свою внешнюю веб-страницу, которая имеет пользовательскую карту Bing, он позволяет мне получить местоположение пользователей как в Android, так и на iOS, но на iOS просит пользовательский сайт ... Хотите использовать ваше текущее местоположение. Дон T Разрешить / ok "Каждый раз, когда они посещают веб-страницу из моего приложения Xamarin.

Я нашел следующие статьи, которые помогут указать мне в правильные направления, но я просто не понимаю достаточно того, чтобы сделать его вместе.
Как предотвратить WKWebView Чтобы неоднократно просить разрешения доступа к определению? - это похоже на то, что мне нужно, но это в iOS и не использует wkwebviewrender, который требуется для более новых приложений iOS.
https://docs.microsoft. COM / EN-US / XAMARIN / XAMARIN-ФОРМЫ / ФОРМАМИ APP / CUSTULD-RENDER / HYBRIDWEBVIEW - это показывает, как добавить «скрипт» на сторону iOS, но я не могу получить метод DidreceivescriptmessAge Пожар.

Вот моя текущая реализация wkwebviewrender.

public class HybridWebViewRenderer : WkWebViewRenderer, IWKScriptMessageHandler
{
    public HybridWebViewRenderer() : this(new WKWebViewConfiguration())
    {
    }        

    const string JavaScriptFunctionTest = 
        "navigator.geolocation.getCurrentPosition = function(success, error, options) {window.webkit.messageHandlers.locationHandler.postMessage('getCurrentPosition');};";

    WKUserContentController userController;

    public HybridWebViewRenderer(WKWebViewConfiguration config) : base(config)
    {
        try
        {
            userController = config.UserContentController;
            var script = new WKUserScript(new NSString(JavaScriptFunctionTest), injectionTime: WKUserScriptInjectionTime.AtDocumentEnd, isForMainFrameOnly: true);
            userController.AddUserScript(script);
            userController.AddScriptMessageHandler(this, "locationHandler");
        }
        catch (System.Exception ex)
        {
                
        }
    }

    public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
    {
        var msg = message.Body.ToString();
        System.Diagnostics.Debug.WriteLine(msg);
    }
}

А вот единственные функции JavaScript на моей HTML-странице.

function StartTracking() {
    //Add a pushpin to show the user's location.
    userPin = new Microsoft.Maps.Pushpin(map.getCenter(), { visible: true });
    map.entities.push(userPin);

    //Watch the users location.
    watchId = navigator.geolocation.watchPosition(UsersLocationUpdated);
}

function UsersLocationUpdated(position) {
    var loc = new Microsoft.Maps.Location(
        position.coords.latitude,
        position.coords.longitude);

    //Update the user pushpin.
    userPin.setLocation(loc);
    userPin.setOptions({ visible: true });

    //Center the map on the user's location.
    map.setView({ center: loc });
}

function StopTracking() {
    // Cancel the geolocation updates.
    navigator.geolocation.clearWatch(watchId);

    //Remove the user pushpin.
    map.entities.clear();
}

https://gist.github.com/hayahyts/2c369563b228f244356eb6228ffba261 но я должен делать что-то не так.
Didreceivescriptmessage не вызывается, если я использую

const string JavaScriptFunction = 
    "navigator.geolocation.getCurrentPosition " + 
    " = function(success, error, options) " + 
    "{window.webkit.messageHandlers.locationHandler.postMessage('getCurrentPosition');};";

Но DidreeceivescriptMessage называется, если я использую

const string JavaScriptFunction = 
    "function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}";

Поэтому я не уверен, что еще не так, но он должен быть с кодом замены местоположенияхHandler.

0
goroth 3 Июн 2021 в 01:03

2 ответа

Лучший ответ

Пространство имен Renderer с атрибутом ExportRenderer:

[assembly: ExportRenderer(typeof(WebView), typeof(MyNamespace.MyWebViewRenderer))]
namespace MyNamespace
{

Декларация рендерера со ссылкой на IWKScriptMessageHandler:

 public class MyWebViewRenderer : WkWebViewRenderer, IWKScriptMessageHandler
 {

Рендерер поля:

  const string MessageHandlerName = "locationHandler";
  const string JavaScriptFunction =
        "navigator.geolocation.getCurrentPosition = function(success, error, options) {window.webkit.messageHandlers.locationHandler.postMessage('getCurrentPosition');};";
  //const string HtmlSource = "html containing navigator.geolocation.getCurrentPosition"

Renderer SetupScripts в OnElementChanged Переопределите:

  protected override void OnElementChanged(VisualElementChangedEventArgs e)
  {
    base.OnElementChanged(e);
    if (e.NewElement != null)
    {
      SetupScripts(Configuration);
      //LoadHtmlString(HtmlSource, null); //example loading page
    }
  }

  void SetupScripts(WKWebViewConfiguration wkWebViewConfig)
  {
    wkWebViewConfig.UserContentController.AddScriptMessageHandler(this, MessageHandlerName);
    var jsFunction = new WKUserScript(new NSString(JavaScriptFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);            
    wkWebViewConfig.UserContentController.AddUserScript(jsFunction);
  }

Рендерер Реализация IWKScriptMessageHandler:

  //IWKScriptMessageHandler
  public void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
  {
     //should be invoked when getCurrentPosition in HtmlSource is invoked
  }
1
Benl 3 Июн 2021 в 15:22

Попробуйте создать новый класс, который наследует от WKScriptMessageHandler для обработки метода DidReceiveScriptMessage.

Измените ваш код, как показано ниже

  1. Изменить Handler
userController.AddScriptMessageHandler(new myClass(), "invokeAction");
  1. Удалить интерфейс WKScriptMessageHandler от HybridWebViewRenderer.
public class HybridWebViewRenderer : WkWebViewRenderer
  1. Создайте подкласс WKScriptMessageHandler .
    public class myClass : WKScriptMessageHandler
    {

        public override void DidReceiveScriptMessage(WKUserContentController userContentController, WKScriptMessage message)
        {
            //_webview.InvokeAction(message.Body.ToString());
        }
    }

Проверьте подобную проблему: https://forums.xamarin.com/discussion / 169893 / WSScriptMessageHandler-IS-не стрельба.

0
ColeX - MSFT 3 Июн 2021 в 09:43