【问题标题】:React-Native's navigator.geolocation is undefinedReact-Native 的 navigator.geolocation 未定义
【发布时间】:2019-09-23 12:54:13
【问题描述】:

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

【问题讨论】:

  • 为什么navigator 会变成WorkerNavigator
  • 你能发布你的Info.plist,如果你正在使用cocoapods
  • 你有RCTGeolocation.xcodeproj作为库下的子项目吗?打开 xcode 并检查库下的部分。分享您创建此项目的方式,默认情况下它应该可以工作。如果您使用 cocoapod 进行反应,则需要添加 subspec RCTGeolocation
  • @manishg 我在库中没有RCTGeolocation.xcodeproj,但我只是添加了它。我还将二进制 libRCTGeolocation.a 链接到库。但是,当我使用 console.log(navigator) 时,我仍然会得到 WorkerNavigator 而没有地理定位选项。

标签: react-native geolocation


【解决方案1】:

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

Web Workers APIWorker 接口代表一个可以轻松创建的后台任务,并且可以将消息发送回其创建者。创建一个worker就像调用Worker()构造函数并指定一个要在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" }

react-native 应用程序中运行导航器将返回一个WorkerNavigator 实例。 WorkerNavigator 是后台任务。

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

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

stackoverflow 上的一些帖子抱怨 ChromeSafari 返回 WorkerNavigator geolocation undefined 并解释为 in the following answer

navigator.geolocation 是否属于navigator 中的Chrome

navigator.geolocation仅属于main thread中的navigator,但不属于worker thread中的navigator

两个导航器在C++ 端有独立的实现。这就是navigator.geolocationworker 线程中不受支持的原因。

Chromium 包含用于 NavigatorWorkerNavigator C++ 实现的独立接口。

NavigatorDOMWindow 的一个属性,而WorkerNavigatorWorkerGlobalScope 的一个属性。

StackOverflow 上的用户抱怨 chrome webworker does not have the geolocation attribute

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

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

geolocation 方法不包含在 WorkerNavigationWorkerLocation 接口中

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

WorkerNavigator api 文档中所述,它不包括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()
  }
});

更多信息here

故障排除问题的步骤

  1. 您正在使用react-native-debugger 工具运行console.log,并且 也许输出是你的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) 将在 react-native-debugger-tools 中返回 WorkerNavigator 对象,而在模拟器中返回 {product:"ReactNative", "geolocation": {}}。 React-native 不会在模拟器中显示console.log

  1. 您是仅在 Iphone 上还是在 Android 上试验此问题?
  2. 您是否错误地将 geolocation 对象导入到您的 组件?

    import { navigator } from ...
    
  3. 你知道native geolocation library 提供更准确的 api 和更广泛的设备支持?

  4. 您的问题似乎与某些未完全连接的浏览器有关 支持WorkerNavigator 接口。你 不同意最后一点,你能给我们提供一些证据吗? 我们错了。 React-Native 正在使用浏览器 api 运行 geolocation 在后台。您可以重新创建相同的场景 在您的iphone emulator safari developer console 中按照此说明创建WorkerNavigator instance,然后检索您的位置。您可以在您的 Emulator Safari/Chrome 浏览器上演示 WorkerNavigator 的工作原理。
  5. 您是否考虑在 w3c/geolocation-api 存储库?有没有考虑开 bug report in chromium?

【讨论】:

  • 那我该如何解决呢?我只想使用navigator.geolocation,但它是未定义的。
  • @TIMEX 我用解决问题的步骤一章更新了我的帖子,我想用react-native-debugger 看到console.warn(navigator)console.warn(navigator.geolocation) 的输出工具被禁用。请向我提供任何其他反馈,以帮助您解决此问题。谢谢
【解决方案2】:

显然,其他人所说的任何事情都无法解决我的问题。 至少对我来说,我使用的是 RN 0.60,我发现他们将它(像许多其他包一样)提取到一个外部包中。 我当然考虑过,考虑到关于所谓的“精益核心”的决定,但在 rn 文档中没有写任何关于位置提取的内容。

所以这是包,在这里您可以找到配置它的新指南: https://github.com/react-native-community/react-native-geolocation

不知道0.59是否也没有

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-17
    • 2021-09-15
    • 2016-09-26
    • 2022-01-21
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多