【发布时间】:2021-08-21 01:59:22
【问题描述】:
我有一个 Xamarin Forms 应用程序,它需要调用一个包含自定义 Bing 地图的网页,并且在网页上它需要能够获取用户的当前位置。
该应用程序已经拥有 Android 和 iOS 所需的“应用程序”权限,我可以毫无问题地在应用程序内部获取用户位置。
当我调用具有自定义 Bing 地图的外部网页时,它确实允许我在 Android 和 iOS 中获取用户位置,但在 iOS 上,它会询问用户“网站......想要使用您当前的位置。不要” t Allow / OK" 每次他们从我的 Xamarin 应用程序中访问网页时。
我发现以下文章可以帮助我指明正确的方向,但我对 iOS 的了解还不够,无法将其拼凑在一起。
How to prevent WKWebView to repeatedly ask for permission to access location? -- 这看起来像是我需要的,但它在 iOS 中并且不使用较新的 iOS 应用程序所需的 WkWebViewRender。
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/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);
}
}
这是我的 html 页面中唯一的 javascript 函数。
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/2c369563b2e9f244356eb6228ffba261 非常接近我的需要,但我一定做错了什么。
如果我使用,DidReceiveScriptMessage 不会被调用
const string JavaScriptFunction =
"navigator.geolocation.getCurrentPosition " +
" = function(success, error, options) " +
"{window.webkit.messageHandlers.locationHandler.postMessage('getCurrentPosition');};";
但是如果我使用 DidReceiveScriptMessage 确实会被调用
const string JavaScriptFunction =
"function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}";
所以我还不确定出了什么问题,但肯定是 locationHandler 替换代码。
【问题讨论】:
标签: ios swift xamarin xamarin.forms xamarin.ios