首页 > 解决方案 > React-Native 的 navigator.geolocation 未定义

问题描述

console.log(navigator.geolocation) //undefined

console.log(navigator)

WorkerNavigator {hardwareConcurrency: 8, appCodeName: "Mozilla", appName: "Netscape", appVersion: "5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKi…L, like Gecko) Chrome/73.0.3683.103 Safari/537.36", …}
appCodeName: "Mozilla"
appName: "Netscape"
appVersion: "5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
connection: NetworkInformation {onchange: null, effectiveType: "4g", rtt: 100, downlink: 4.3, saveData: false}
deviceMemory: 8
hardwareConcurrency: 8
language: "en-US"
languages: (3) ["en-US", "en", "es"]
locks: LockManager {}
onLine: true
permissions: Permissions {}
platform: "MacIntel"
product: (...)
storage: StorageManager {}
usb: USB {onconnect: null, ondisconnect: null}
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
get product: ƒ getValue()
set product: ƒ setValue(newValue)
__proto__: WorkerNavigator

我在 iOS 上使用 React Native 0.59。

在 info.plist 中,我同时拥有:Privacy - Location When In Use Usage DescriptionPrivacy - Location Always and When In Use Usage Description

CocoaPods:http ://dpaste.com/2W9Y57E Info.plist:http ://dpaste.com/1CTG8GP

标签: react-nativegeolocation

解决方案


WorkerNavigator接口表示允许从Worker. 这样的对象是为每个工人初始化的,并且可以通过WorkerGlobalScope.navigator调用获得的属性获得window.self.navigator

Web Workers APIWorker接口代表一个后台任务,可以轻松创建并可以将消息发送回其创建者。创建工作线程就像调用构造函数并指定要在工作线程中运行的脚本一样简单。Worker()

navigator在任何网页上运行都会返回一个Navigator实例

>> navigator
Navigator { permissions: Permissions, mimeTypes: MimeTypeArray, plugins: PluginArray, doNotTrack: "unspecified", maxTouchPoints: 0, mediaCapabilities: MediaCapabilities, oscpu: "Intel Mac OS X 10.13", vendor: "", vendorSub: "", productSub: "20100101" }

在应用程序内运行 navigatorreact-native将返回一个WorkerNavigator实例。这WorkerNavigator是一个后台任务。

>> navigator
WorkerNavigator { geolocation: Object, hardwareConcurrency: 4, appCodeName: "Mozilla", appName: "Netscape"… }

WorkerNavigator界面不完全兼容/测试所有浏览器,但我在Iphone X模拟器上测试了功能并且navigator.geolocationdefined.

Worker Navigator 与浏览器的兼容性

stackoverflow 上的几篇帖子抱怨ChromeSafari返回WorkerNavigator geolocation undefined,如以下答案中所述

navigator.geolocation属于navigatorin ?Chrome_

navigator.geolocation属于唯一navigatormain thread但不navigator属于worker thread

C++两个导航器在侧面有独立的实现。这就是线程navigator.geolocation不支持的原因。worker

Chromium 包括用于NavigatorWorkerNavigatorC++ 实现的分离接口。

Navigator是 的属性DOMWindow,而WorkerNavigator是 的属性WorkerGlobalScope

StackOverflow 上的用户抱怨chrome webworker 没有该geolocation属性

WorkerGlobalScope 接口的 navigator 属性必须返回一个 WorkerNavigator 接口的实例,它代表了用户代理(客户端)的身份和状态:

[Exposed=Worker]
interface WorkerNavigator {};
WorkerNavigator includes NavigatorID;
WorkerNavigator includes NavigatorLanguage;
WorkerNavigator includes NavigatorOnLine;
WorkerNavigator includes NavigatorConcurrentHardware;

和接口geolocation中不包含该方法WorkerNavigationWorkerLocation

Navigator为每个工人初始化,可通过调用获得的属性WorkerGlobalScope.navigator获得window.self.navigator

WorkerNavigatorapi 文档中所述,它不包括该geolocation()方法。

如果您仍然遇到此问题,您可以考虑遵循本指南,手动创建您worker的方法并在不同的浏览器上测试这些方法。

navigator.permissions?检测地理位置支持

WorkerNavigator.permissions只读属性返回一个对象,该Permissions对象可用于查询和更新 Permissions API 所涵盖的 API 的权限状态。

self.permissions.query({name:'notifications'}).then(function(result) {
  if (result.state === 'granted') {
    showNotification();
  } else if (result.state === 'prompt') {
    requestNotificationPermission()
  }
});

更多信息在这里

解决问题的步骤

  1. 您正在console.log使用这些react-native-debugger工具运行,也许输出是您的 mac 浏览器而不是您的手机给出的输出。debugging在您的模拟器上禁用并向我们展示console.warn(navigator)和的输出console.warn(navigator.geolocation)

    appVersion: "5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103
    Safari/537.36"
    

如下图所示,console.warn(navigator)将在 中返回一个WorkerNavigatorObject react-native-debugger-tools,而{product:"ReactNative", "geolocation": {}}在模拟器中返回。React-native 不会显示console.log模拟器内部。

在此处输入图像描述

  1. 你是只在 Iphone 上还是在 Android 上试验这个问题?
  2. 您是否错误地将对象导入到geolocation组件之上?

    import { navigator } from ...
    
  3. 你知道原生地理定位库 提供了更准确的 api 和更广泛的设备支持吗?

  4. 您的问题似乎与某些不完全支持该WorkerNavigator界面的浏览器有关。您是否不同意最后一点,您能否向我们提供一些证明我们错了的证据。React-Native正在使用浏览器 api geolocation在后台运行。您可以按照此说明在iphone 模拟器 safari中重新创建相同的场景以创建developer consoleWorkerNavigator实例,然后检索您的位置。WorkerNavigator您可以在您的模拟器 Safari/Chrome 浏览器上演示这些作品。
  5. 您是否考虑在 w3c/geolocation-api存储库中打开问题?您是否考虑过在 chromium 中打开错误报告

推荐阅读