@capacitor/geolocation 7.1.5-dev.5 → 7.1.5-dev.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,8 +11,8 @@ Pod::Spec.new do |s|
11
11
  s.author = package['author']
12
12
  s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
13
  s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
14
- s.ios.deployment_target = '14.0'
14
+ s.ios.deployment_target = '15.0'
15
15
  s.dependency 'Capacitor'
16
- #s.dependency 'IONGeolocationLib', spec='1.0.1'
16
+ s.dependency 'IONGeolocationLib', spec='2.0.0'
17
17
  s.swift_version = '5.1'
18
18
  end
package/Package.swift CHANGED
@@ -3,7 +3,7 @@ import PackageDescription
3
3
 
4
4
  let package = Package(
5
5
  name: "CapacitorGeolocation",
6
- platforms: [.iOS(.v14)],
6
+ platforms: [.iOS(.v15)],
7
7
  products: [
8
8
  .library(
9
9
  name: "CapacitorGeolocation",
@@ -11,7 +11,7 @@ let package = Package(
11
11
  ],
12
12
  dependencies: [
13
13
  .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.0.0"),
14
- .package(url: "https://github.com/ionic-team/ion-ios-geolocation.git", from: "1.0.2")
14
+ .package(url: "https://github.com/ionic-team/ion-ios-geolocation.git", from: "2.0.0")
15
15
  ],
16
16
  targets: [
17
17
  .target(
package/README.md CHANGED
@@ -167,12 +167,13 @@ Not available on web.
167
167
 
168
168
  #### PositionOptions
169
169
 
170
- | Prop | Type | Description | Default | Since |
171
- | --------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
172
- | **`enableHighAccuracy`** | <code>boolean</code> | High accuracy mode (such as GPS, if available) On Android 12+ devices it will be ignored if users didn't grant ACCESS_FINE_LOCATION permissions (can be checked with location alias). | <code>false</code> | 1.0.0 |
173
- | **`timeout`** | <code>number</code> | The maximum wait time in milliseconds for location updates. In Android, since version 7.1.0 of the plugin, it is also used to determine the interval of location updates for `watchPosition`. | <code>10000</code> | 1.0.0 |
174
- | **`maximumAge`** | <code>number</code> | The maximum age in milliseconds of a possible cached position that is acceptable to return | <code>0</code> | 1.0.0 |
175
- | **`minimumUpdateInterval`** | <code>number</code> | The minumum update interval for location updates. If location updates are available faster than this interval then an update will only occur if the minimum update interval has expired since the last location update. This parameter is only available for Android. It has no effect on iOS or Web platforms. | <code>5000</code> | 6.1.0 |
170
+ | Prop | Type | Description | Default | Since |
171
+ | ---------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ----- |
172
+ | **`enableHighAccuracy`** | <code>boolean</code> | High accuracy mode (such as GPS, if available) On Android 12+ devices it will be ignored if users didn't grant ACCESS_FINE_LOCATION permissions (can be checked with location alias). | <code>false</code> | 1.0.0 |
173
+ | **`timeout`** | <code>number</code> | The maximum wait time in milliseconds for location updates. In Android, since version 7.1.0 of the plugin, it is also used to determine the interval of location updates for `watchPosition`. | <code>10000</code> | 1.0.0 |
174
+ | **`maximumAge`** | <code>number</code> | The maximum age in milliseconds of a possible cached position that is acceptable to return | <code>0</code> | 1.0.0 |
175
+ | **`minimumUpdateInterval`** | <code>number</code> | The minumum update interval for location updates. If location updates are available faster than this interval then an update will only occur if the minimum update interval has expired since the last location update. This parameter is only available for Android. It has no effect on iOS or Web platforms. | <code>5000</code> | 6.1.0 |
176
+ | **`enableLocationFallback`** | <code>boolean</code> | This option applies to Android only. Whether to fall back to the Android framework's `LocationManager` in case Google Play Service's location settings checks fail. This can happen for multiple reasons - e.g. device has no Play Services or device has no network connection (Airplane Mode) If set to `false`, failures are propagated to the caller. Note that `LocationManager` may not be as effective as Google Play Services implementation. If the device's in airplane mode, only the GPS provider is used, which may take longer to return a location, depending on GPS signal. This means that to receive location in such circumstances, you may need to provide a higher timeout. | <code>true</code> | 8.0.0 |
176
177
 
177
178
 
178
179
  #### ClearWatchOptions
@@ -237,10 +238,11 @@ The following table list all the plugin errors:
237
238
  | OS-PLUG-GLOC-0007 | Android, iOS | Location services are not enabled. |
238
239
  | OS-PLUG-GLOC-0008 | iOS | Application's use of location services was restricted. |
239
240
  | OS-PLUG-GLOC-0009 | Android | Request to enable location was denied. |
240
- | OS-PLUG-GLOC-0010 | Android | Could not obtain location in time. Try with a higher timeout. |
241
+ | OS-PLUG-GLOC-0010 | Android, iOS | Could not obtain location in time. Try with a higher timeout. |
241
242
  | OS-PLUG-GLOC-0011 | Android | Timeout needs to be a positive value. |
242
243
  | OS-PLUG-GLOC-0012 | Android | WatchId not found. |
243
244
  | OS-PLUG-GLOC-0013 | Android | WatchId needs to be provided. |
244
245
  | OS-PLUG-GLOC-0014 | Android | Google Play Services error user resolvable. |
245
246
  | OS-PLUG-GLOC-0015 | Android | Google Play Services error. |
246
247
  | OS-PLUG-GLOC-0016 | Android | Location settings error. |
248
+ | OS-PLUG-GLOC-0017 | Android | Unable to retrieve location because device has both Network and Location turned off. |
@@ -23,10 +23,10 @@ apply plugin: 'kotlin-android'
23
23
 
24
24
  android {
25
25
  namespace "com.capacitorjs.plugins.geolocation"
26
- compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 35
26
+ compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
27
27
  defaultConfig {
28
- minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23
29
- targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 35
28
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 24
29
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
30
30
  versionCode 1
31
31
  versionName "1.0"
32
32
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -58,7 +58,7 @@ repositories {
58
58
 
59
59
  dependencies {
60
60
  implementation fileTree(dir: 'libs', include: ['*.jar'])
61
- implementation("io.ionic.libs:iongeolocation-android:1.0.0")
61
+ implementation("io.ionic.libs:iongeolocation-android:2.0.0")
62
62
  implementation project(':capacitor-android')
63
63
  implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
64
64
 
@@ -68,4 +68,9 @@ object GeolocationErrors {
68
68
  code = formatErrorCode(16),
69
69
  message = "Location settings error."
70
70
  )
71
+
72
+ val NETWORK_LOCATION_DISABLED_ERROR = ErrorInfo(
73
+ code = formatErrorCode(17),
74
+ message = "Unable to retrieve location because device has both Network and Location turned off."
75
+ )
71
76
  }
@@ -54,11 +54,7 @@ class GeolocationPlugin : Plugin() {
54
54
  }
55
55
  }
56
56
 
57
- this.controller = IONGLOCController(
58
- LocationServices.getFusedLocationProviderClient(context),
59
- activityLauncher
60
- )
61
-
57
+ this.controller = IONGLOCController(context, activityLauncher)
62
58
  }
63
59
 
64
60
  override fun handleOnDestroy() {
@@ -82,7 +78,7 @@ class GeolocationPlugin : Plugin() {
82
78
  * @param onLocationEnabled lambda function to use in case location services are enabled
83
79
  */
84
80
  private fun checkLocationState(call: PluginCall, onLocationEnabled: () -> Unit) {
85
- if (controller.areLocationServicesEnabled(context)) {
81
+ if (controller.areLocationServicesEnabled()) {
86
82
  onLocationEnabled()
87
83
  } else {
88
84
  call.sendError(GeolocationErrors.LOCATION_DISABLED)
@@ -279,6 +275,9 @@ class GeolocationPlugin : Plugin() {
279
275
  is IONGLOCException.IONGLOCSettingsException -> {
280
276
  call.sendError(GeolocationErrors.LOCATION_SETTINGS_ERROR)
281
277
  }
278
+ is IONGLOCException.IONGLOCLocationAndNetworkDisabledException -> {
279
+ call.sendError(GeolocationErrors.NETWORK_LOCATION_DISABLED_ERROR)
280
+ }
282
281
  is IONGLOCException.IONGLOCInvalidTimeoutException -> {
283
282
  call.sendError(GeolocationErrors.INVALID_TIMEOUT)
284
283
  }
@@ -330,8 +329,15 @@ class GeolocationPlugin : Plugin() {
330
329
  val maximumAge = call.getNumber("maximumAge", 0)
331
330
  val enableHighAccuracy = call.getBoolean("enableHighAccuracy", false) ?: false
332
331
  val minimumUpdateInterval = call.getNumber("minimumUpdateInterval", 5000)
333
-
334
- val locationOptions = IONGLOCLocationOptions(timeout, maximumAge, enableHighAccuracy, minimumUpdateInterval)
332
+ val enableLocationFallback = call.getBoolean("enableLocationFallback", true) ?: true
333
+
334
+ val locationOptions = IONGLOCLocationOptions(
335
+ timeout,
336
+ maximumAge,
337
+ enableHighAccuracy,
338
+ enableLocationFallback,
339
+ minimumUpdateInterval
340
+ )
335
341
 
336
342
  return locationOptions
337
343
  }
package/dist/docs.json CHANGED
@@ -230,6 +230,22 @@
230
230
  "docs": "The minumum update interval for location updates.\n\nIf location updates are available faster than this interval then an update\nwill only occur if the minimum update interval has expired since the last location update.\n\nThis parameter is only available for Android. It has no effect on iOS or Web platforms.",
231
231
  "complexTypes": [],
232
232
  "type": "number | undefined"
233
+ },
234
+ {
235
+ "name": "enableLocationFallback",
236
+ "tags": [
237
+ {
238
+ "text": "true",
239
+ "name": "default"
240
+ },
241
+ {
242
+ "text": "8.0.0",
243
+ "name": "since"
244
+ }
245
+ ],
246
+ "docs": "This option applies to Android only.\n\nWhether to fall back to the Android framework's `LocationManager` in case Google Play Service's location settings checks fail.\nThis can happen for multiple reasons - e.g. device has no Play Services or device has no network connection (Airplane Mode)\nIf set to `false`, failures are propagated to the caller.\nNote that `LocationManager` may not be as effective as Google Play Services implementation.\nIf the device's in airplane mode, only the GPS provider is used, which may take longer to return a location, depending on GPS signal.\nThis means that to receive location in such circumstances, you may need to provide a higher timeout.",
247
+ "complexTypes": [],
248
+ "type": "boolean | undefined"
233
249
  }
234
250
  ]
235
251
  },
@@ -168,6 +168,20 @@ export interface PositionOptions {
168
168
  * @since 6.1.0
169
169
  */
170
170
  minimumUpdateInterval?: number;
171
+ /**
172
+ * This option applies to Android only.
173
+ *
174
+ * Whether to fall back to the Android framework's `LocationManager` in case Google Play Service's location settings checks fail.
175
+ * This can happen for multiple reasons - e.g. device has no Play Services or device has no network connection (Airplane Mode)
176
+ * If set to `false`, failures are propagated to the caller.
177
+ * Note that `LocationManager` may not be as effective as Google Play Services implementation.
178
+ * If the device's in airplane mode, only the GPS provider is used, which may take longer to return a location, depending on GPS signal.
179
+ * This means that to receive location in such circumstances, you may need to provide a higher timeout.
180
+ *
181
+ * @default true
182
+ * @since 8.0.0
183
+ */
184
+ enableLocationFallback?: boolean;
171
185
  }
172
186
  export type WatchPositionCallback = (position: Position | null, err?: any) => void;
173
187
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PermissionState } from '@capacitor/core';\n\nexport type CallbackID = string;\n\nexport interface PermissionStatus {\n /**\n * Permission state for location alias.\n *\n * On Android it requests/checks both ACCESS_COARSE_LOCATION and\n * ACCESS_FINE_LOCATION permissions.\n *\n * On iOS and web it requests/checks location permission.\n *\n * @since 1.0.0\n */\n location: PermissionState;\n\n /**\n * Permission state for coarseLocation alias.\n *\n * On Android it requests/checks ACCESS_COARSE_LOCATION.\n *\n * On Android 12+, users can choose between Approximate location (ACCESS_COARSE_LOCATION) or\n * Precise location (ACCESS_FINE_LOCATION), so this alias can be used if the app doesn't\n * need high accuracy.\n *\n * On iOS and web it will have the same value as location alias.\n *\n * @since 1.2.0\n */\n coarseLocation: PermissionState;\n}\n\nexport type GeolocationPermissionType = 'location' | 'coarseLocation';\n\nexport interface GeolocationPluginPermissions {\n permissions: GeolocationPermissionType[];\n}\n\nexport interface GeolocationPlugin {\n /**\n * Get the current GPS location of the device\n *\n * @since 1.0.0\n */\n getCurrentPosition(options?: PositionOptions): Promise<Position>;\n\n /**\n * Set up a watch for location changes. Note that watching for location changes\n * can consume a large amount of energy. Be smart about listening only when you need to.\n *\n * @since 1.0.0\n */\n watchPosition(options: PositionOptions, callback: WatchPositionCallback): Promise<CallbackID>;\n\n /**\n * Clear a given watch\n *\n * @since 1.0.0\n */\n clearWatch(options: ClearWatchOptions): Promise<void>;\n\n /**\n * Check location permissions. Will throw if system location services are disabled.\n *\n * @since 1.0.0\n */\n checkPermissions(): Promise<PermissionStatus>;\n\n /**\n * Request location permissions. Will throw if system location services are disabled.\n *\n * Not available on web.\n *\n * @since 1.0.0\n */\n requestPermissions(permissions?: GeolocationPluginPermissions): Promise<PermissionStatus>;\n}\n\nexport interface ClearWatchOptions {\n id: CallbackID;\n}\n\nexport interface Position {\n /**\n * Creation timestamp for coords\n *\n * @since 1.0.0\n */\n timestamp: number;\n\n /**\n * The GPS coordinates along with the accuracy of the data\n *\n * @since 1.0.0\n */\n coords: {\n /**\n * Latitude in decimal degrees\n *\n * @since 1.0.0\n */\n latitude: number;\n\n /**\n * longitude in decimal degrees\n *\n * @since 1.0.0\n */\n longitude: number;\n\n /**\n * Accuracy level of the latitude and longitude coordinates in meters\n *\n * @since 1.0.0\n */\n accuracy: number;\n\n /**\n * Accuracy level of the altitude coordinate in meters, if available.\n *\n * Available on all iOS versions and on Android 8.0+.\n *\n * @since 1.0.0\n */\n altitudeAccuracy: number | null | undefined;\n\n /**\n * The altitude the user is at (if available)\n *\n * @since 1.0.0\n */\n altitude: number | null;\n\n /**\n * The speed the user is traveling (if available)\n *\n * @since 1.0.0\n */\n speed: number | null;\n\n /**\n * The heading the user is facing (if available)\n *\n * @since 1.0.0\n */\n heading: number | null;\n };\n}\n\nexport interface PositionOptions {\n /**\n * High accuracy mode (such as GPS, if available)\n *\n * On Android 12+ devices it will be ignored if users didn't grant\n * ACCESS_FINE_LOCATION permissions (can be checked with location alias).\n *\n * @default false\n * @since 1.0.0\n */\n enableHighAccuracy?: boolean;\n\n /**\n * The maximum wait time in milliseconds for location updates.\n *\n * In Android, since version 7.1.0 of the plugin, it is also used to determine the\n * interval of location updates for `watchPosition`.\n *\n * @default 10000\n * @since 1.0.0\n */\n timeout?: number;\n\n /**\n * The maximum age in milliseconds of a possible cached position that is acceptable to return\n *\n * @default 0\n * @since 1.0.0\n */\n maximumAge?: number;\n\n /**\n * The minumum update interval for location updates.\n *\n * If location updates are available faster than this interval then an update\n * will only occur if the minimum update interval has expired since the last location update.\n *\n * This parameter is only available for Android. It has no effect on iOS or Web platforms.\n *\n * @default 5000\n * @since 6.1.0\n */\n minimumUpdateInterval?: number;\n}\n\nexport type WatchPositionCallback = (position: Position | null, err?: any) => void;\n\n/**\n * @deprecated Use `PositionOptions`.\n * @since 1.0.0\n */\nexport type GeolocationOptions = PositionOptions;\n\n/**\n * @deprecated Use `WatchPositionCallback`.\n * @since 1.0.0\n */\nexport type GeolocationWatchCallback = WatchPositionCallback;\n\n/**\n * @deprecated Use `Position`.\n * @since 1.0.0\n */\nexport type GeolocationPosition = Position;\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PermissionState } from '@capacitor/core';\n\nexport type CallbackID = string;\n\nexport interface PermissionStatus {\n /**\n * Permission state for location alias.\n *\n * On Android it requests/checks both ACCESS_COARSE_LOCATION and\n * ACCESS_FINE_LOCATION permissions.\n *\n * On iOS and web it requests/checks location permission.\n *\n * @since 1.0.0\n */\n location: PermissionState;\n\n /**\n * Permission state for coarseLocation alias.\n *\n * On Android it requests/checks ACCESS_COARSE_LOCATION.\n *\n * On Android 12+, users can choose between Approximate location (ACCESS_COARSE_LOCATION) or\n * Precise location (ACCESS_FINE_LOCATION), so this alias can be used if the app doesn't\n * need high accuracy.\n *\n * On iOS and web it will have the same value as location alias.\n *\n * @since 1.2.0\n */\n coarseLocation: PermissionState;\n}\n\nexport type GeolocationPermissionType = 'location' | 'coarseLocation';\n\nexport interface GeolocationPluginPermissions {\n permissions: GeolocationPermissionType[];\n}\n\nexport interface GeolocationPlugin {\n /**\n * Get the current GPS location of the device\n *\n * @since 1.0.0\n */\n getCurrentPosition(options?: PositionOptions): Promise<Position>;\n\n /**\n * Set up a watch for location changes. Note that watching for location changes\n * can consume a large amount of energy. Be smart about listening only when you need to.\n *\n * @since 1.0.0\n */\n watchPosition(options: PositionOptions, callback: WatchPositionCallback): Promise<CallbackID>;\n\n /**\n * Clear a given watch\n *\n * @since 1.0.0\n */\n clearWatch(options: ClearWatchOptions): Promise<void>;\n\n /**\n * Check location permissions. Will throw if system location services are disabled.\n *\n * @since 1.0.0\n */\n checkPermissions(): Promise<PermissionStatus>;\n\n /**\n * Request location permissions. Will throw if system location services are disabled.\n *\n * Not available on web.\n *\n * @since 1.0.0\n */\n requestPermissions(permissions?: GeolocationPluginPermissions): Promise<PermissionStatus>;\n}\n\nexport interface ClearWatchOptions {\n id: CallbackID;\n}\n\nexport interface Position {\n /**\n * Creation timestamp for coords\n *\n * @since 1.0.0\n */\n timestamp: number;\n\n /**\n * The GPS coordinates along with the accuracy of the data\n *\n * @since 1.0.0\n */\n coords: {\n /**\n * Latitude in decimal degrees\n *\n * @since 1.0.0\n */\n latitude: number;\n\n /**\n * longitude in decimal degrees\n *\n * @since 1.0.0\n */\n longitude: number;\n\n /**\n * Accuracy level of the latitude and longitude coordinates in meters\n *\n * @since 1.0.0\n */\n accuracy: number;\n\n /**\n * Accuracy level of the altitude coordinate in meters, if available.\n *\n * Available on all iOS versions and on Android 8.0+.\n *\n * @since 1.0.0\n */\n altitudeAccuracy: number | null | undefined;\n\n /**\n * The altitude the user is at (if available)\n *\n * @since 1.0.0\n */\n altitude: number | null;\n\n /**\n * The speed the user is traveling (if available)\n *\n * @since 1.0.0\n */\n speed: number | null;\n\n /**\n * The heading the user is facing (if available)\n *\n * @since 1.0.0\n */\n heading: number | null;\n };\n}\n\nexport interface PositionOptions {\n /**\n * High accuracy mode (such as GPS, if available)\n *\n * On Android 12+ devices it will be ignored if users didn't grant\n * ACCESS_FINE_LOCATION permissions (can be checked with location alias).\n *\n * @default false\n * @since 1.0.0\n */\n enableHighAccuracy?: boolean;\n\n /**\n * The maximum wait time in milliseconds for location updates.\n *\n * In Android, since version 7.1.0 of the plugin, it is also used to determine the\n * interval of location updates for `watchPosition`.\n *\n * @default 10000\n * @since 1.0.0\n */\n timeout?: number;\n\n /**\n * The maximum age in milliseconds of a possible cached position that is acceptable to return\n *\n * @default 0\n * @since 1.0.0\n */\n maximumAge?: number;\n\n /**\n * The minumum update interval for location updates.\n *\n * If location updates are available faster than this interval then an update\n * will only occur if the minimum update interval has expired since the last location update.\n *\n * This parameter is only available for Android. It has no effect on iOS or Web platforms.\n *\n * @default 5000\n * @since 6.1.0\n */\n minimumUpdateInterval?: number;\n\n /**\n * This option applies to Android only.\n *\n * Whether to fall back to the Android framework's `LocationManager` in case Google Play Service's location settings checks fail.\n * This can happen for multiple reasons - e.g. device has no Play Services or device has no network connection (Airplane Mode)\n * If set to `false`, failures are propagated to the caller.\n * Note that `LocationManager` may not be as effective as Google Play Services implementation.\n * If the device's in airplane mode, only the GPS provider is used, which may take longer to return a location, depending on GPS signal.\n * This means that to receive location in such circumstances, you may need to provide a higher timeout.\n *\n * @default true\n * @since 8.0.0\n */\n enableLocationFallback?: boolean;\n}\n\nexport type WatchPositionCallback = (position: Position | null, err?: any) => void;\n\n/**\n * @deprecated Use `PositionOptions`.\n * @since 1.0.0\n */\nexport type GeolocationOptions = PositionOptions;\n\n/**\n * @deprecated Use `WatchPositionCallback`.\n * @since 1.0.0\n */\nexport type GeolocationWatchCallback = WatchPositionCallback;\n\n/**\n * @deprecated Use `Position`.\n * @since 1.0.0\n */\nexport type GeolocationPosition = Position;\n"]}
@@ -1,5 +1,5 @@
1
1
  import Capacitor
2
- //import IONGeolocationLib
2
+ import IONGeolocationLib
3
3
 
4
4
  private enum GeolocationCallbackType {
5
5
  case requestPermissions
@@ -24,6 +24,7 @@ final class GeolocationCallbackManager {
24
24
  private(set) var requestPermissionsCallbacks: [CAPPluginCall]
25
25
  private(set) var locationCallbacks: [CAPPluginCall]
26
26
  private(set) var watchCallbacks: [String: CAPPluginCall]
27
+ private(set) var timeout: Int?
27
28
  private let capacitorBridge: CAPBridgeProtocol?
28
29
 
29
30
  private var allCallbackGroups: [GeolocationCallbackGroup] {
@@ -52,11 +53,15 @@ final class GeolocationCallbackManager {
52
53
  func addLocationCallback(capacitorCall call: CAPPluginCall) {
53
54
  capacitorBridge?.saveCall(call)
54
55
  locationCallbacks.append(call)
56
+ let timeout = call.getInt(Constants.Arguments.timeout)
57
+ self.timeout = timeout
55
58
  }
56
59
 
57
60
  func addWatchCallback(_ watchId: String, capacitorCall call: CAPPluginCall) {
58
61
  capacitorBridge?.saveCall(call)
59
62
  watchCallbacks[watchId] = call
63
+ let timeout = call.getInt(Constants.Arguments.timeout)
64
+ self.timeout = timeout
60
65
  }
61
66
 
62
67
  func clearRequestPermissionsCallbacks() {
@@ -2,6 +2,7 @@ enum Constants {
2
2
  enum Arguments {
3
3
  static let enableHighAccuracy = "enableHighAccuracy"
4
4
  static let id = "id"
5
+ static let timeout = "timeout"
5
6
  }
6
7
 
7
8
  enum AuthorisationStatus {
@@ -1,5 +1,5 @@
1
1
  import Capacitor
2
- // import IONGeolocationLib
2
+ import IONGeolocationLib
3
3
  import UIKit
4
4
  import Combine
5
5
 
@@ -58,7 +58,6 @@ public class GeolocationPlugin: CAPPlugin, CAPBridgedPlugin {
58
58
  @objc func getCurrentPosition(_ call: CAPPluginCall) {
59
59
  shouldSetupBindings()
60
60
  let enableHighAccuracy = call.getBool(Constants.Arguments.enableHighAccuracy, false)
61
- self.timeout = call.getInt("timeout")
62
61
  handleLocationRequest(enableHighAccuracy, call: call)
63
62
  }
64
63
 
@@ -66,7 +65,6 @@ public class GeolocationPlugin: CAPPlugin, CAPBridgedPlugin {
66
65
  shouldSetupBindings()
67
66
  let enableHighAccuracy = call.getBool(Constants.Arguments.enableHighAccuracy, false)
68
67
  let watchUUID = call.callbackId
69
- self.timeout = call.getInt("timeout")
70
68
  handleLocationRequest(enableHighAccuracy, watchUUID: watchUUID, call: call)
71
69
  }
72
70
 
@@ -216,10 +214,10 @@ private extension GeolocationPlugin {
216
214
  callbackManager?.sendRequestPermissionsSuccess(Constants.AuthorisationStatus.Status.granted)
217
215
  }
218
216
  if shouldRequestCurrentPosition {
219
- locationService?.requestSingleLocation(options: IONGLOCRequestOptionsModel(timeout: self.timeout))
217
+ locationService?.requestSingleLocation(options: IONGLOCRequestOptionsModel(timeout: callbackManager?.timeout))
220
218
  }
221
219
  if shouldRequestLocationMonitoring {
222
- locationService?.startMonitoringLocation(options: IONGLOCRequestOptionsModel(timeout: self.timeout))
220
+ locationService?.startMonitoringLocation(options: IONGLOCRequestOptionsModel(timeout: callbackManager?.timeout))
223
221
  }
224
222
  }
225
223
 
@@ -1,5 +1,5 @@
1
1
  import Capacitor
2
- //import IONGeolocationLib
2
+ import IONGeolocationLib
3
3
 
4
4
  extension IONGLOCPositionModel {
5
5
  func toJSObject() -> JSObject {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/geolocation",
3
- "version": "7.1.5-dev.5",
3
+ "version": "7.1.5-dev.7",
4
4
  "description": "The Geolocation API provides simple methods for getting and tracking the current position of the device using GPS, along with altitude, heading, and speed information if available.",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
@@ -46,7 +46,7 @@
46
46
  "prepublishOnly": "npm run build"
47
47
  },
48
48
  "dependencies": {
49
- "@capacitor/synapse": "^1.0.3"
49
+ "@capacitor/synapse": "^1.0.4"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@capacitor/android": "next",
@@ -72,7 +72,7 @@
72
72
  "typescript": "~5.4.5"
73
73
  },
74
74
  "peerDependencies": {
75
- "@capacitor/core": ">=7.0.0"
75
+ "@capacitor/core": ">=8.0.0-alpha.2"
76
76
  },
77
77
  "prettier": "@ionic/prettier-config",
78
78
  "swiftlint": "@ionic/swiftlint-config",
@@ -1,26 +0,0 @@
1
- import CoreLocation
2
-
3
- public enum IONGLOCAuthorisation {
4
- case notDetermined
5
- case restricted
6
- case denied
7
- case authorisedAlways
8
- case authorisedWhenInUse
9
-
10
- init(from status: CLAuthorizationStatus) {
11
- self = switch status {
12
- case .notDetermined: .notDetermined
13
- case .restricted: .restricted
14
- case .denied: .denied
15
- case .authorizedAlways: .authorisedAlways
16
- case .authorizedWhenInUse: .authorisedWhenInUse
17
- @unknown default: .notDetermined
18
- }
19
- }
20
- }
21
-
22
- extension CLLocationManager {
23
- var currentAuthorisationValue: IONGLOCAuthorisation {
24
- .init(from: authorizationStatus)
25
- }
26
- }
@@ -1,16 +0,0 @@
1
- import CoreLocation
2
-
3
- public enum IONGLOCAuthorisationRequestType {
4
- case whenInUse
5
- case always
6
-
7
- func requestAuthorization(using locationManager: CLLocationManager) {
8
- let requestAuthorisation = switch self {
9
- case .whenInUse:
10
- locationManager.requestWhenInUseAuthorization
11
- case .always:
12
- locationManager.requestAlwaysAuthorization
13
- }
14
- requestAuthorisation()
15
- }
16
- }
@@ -1,44 +0,0 @@
1
- import CoreLocation
2
-
3
- public struct IONGLOCPositionModel: Equatable {
4
- private(set) public var altitude: Double
5
- private(set) public var course: Double
6
- private(set) public var horizontalAccuracy: Double
7
- private(set) public var latitude: Double
8
- private(set) public var longitude: Double
9
- private(set) public var speed: Double
10
- private(set) public var timestamp: Double
11
- private(set) public var verticalAccuracy: Double
12
-
13
- private init(altitude: Double, course: Double, horizontalAccuracy: Double, latitude: Double, longitude: Double, speed: Double, timestamp: Double, verticalAccuracy: Double) {
14
- self.altitude = altitude
15
- self.course = course
16
- self.horizontalAccuracy = horizontalAccuracy
17
- self.latitude = latitude
18
- self.longitude = longitude
19
- self.speed = speed
20
- self.timestamp = timestamp
21
- self.verticalAccuracy = verticalAccuracy
22
- }
23
- }
24
-
25
- public extension IONGLOCPositionModel {
26
- static func create(from location: CLLocation) -> IONGLOCPositionModel {
27
- .init(
28
- altitude: location.altitude,
29
- course: location.course,
30
- horizontalAccuracy: location.horizontalAccuracy,
31
- latitude: location.coordinate.latitude,
32
- longitude: location.coordinate.longitude,
33
- speed: location.speed,
34
- timestamp: location.timestamp.millisecondsSinceUnixEpoch,
35
- verticalAccuracy: location.verticalAccuracy
36
- )
37
- }
38
- }
39
-
40
- private extension Date {
41
- var millisecondsSinceUnixEpoch: Double {
42
- timeIntervalSince1970 * 1000
43
- }
44
- }
@@ -1,9 +0,0 @@
1
- import Foundation
2
-
3
- public struct IONGLOCRequestOptionsModel {
4
- let timeout: Int
5
-
6
- public init(timeout: Int? = nil) {
7
- self.timeout = timeout ?? 5000
8
- }
9
- }
@@ -1,45 +0,0 @@
1
- import Combine
2
-
3
- public protocol IONGLOCServicesChecker {
4
- func areLocationServicesEnabled() -> Bool
5
- }
6
-
7
- public protocol IONGLOCAuthorisationHandler {
8
- var authorisationStatus: IONGLOCAuthorisation { get }
9
- var authorisationStatusPublisher: Published<IONGLOCAuthorisation>.Publisher { get }
10
-
11
- func requestAuthorisation(withType authorisationType: IONGLOCAuthorisationRequestType)
12
- }
13
-
14
- public enum IONGLOCLocationError: Error {
15
- case locationUnavailable
16
- case timeout
17
- case other(_ error: Error)
18
- }
19
-
20
- public protocol IONGLOCLocationHandler {
21
- var currentLocation: IONGLOCPositionModel? { get }
22
- var currentLocationPublisher: AnyPublisher<IONGLOCPositionModel, IONGLOCLocationError> { get }
23
- var locationTimeoutPublisher: AnyPublisher<IONGLOCLocationError, Never> { get }
24
- func updateConfiguration(_ configuration: IONGLOCConfigurationModel)
25
- }
26
-
27
- public protocol IONGLOCSingleLocationHandler: IONGLOCLocationHandler {
28
- func requestSingleLocation(options: IONGLOCRequestOptionsModel)
29
- }
30
-
31
- public protocol IONGLOCMonitorLocationHandler: IONGLOCLocationHandler {
32
- func startMonitoringLocation(options: IONGLOCRequestOptionsModel)
33
- func startMonitoringLocation()
34
- func stopMonitoringLocation()
35
- }
36
-
37
- public struct IONGLOCConfigurationModel {
38
- private(set) var enableHighAccuracy: Bool
39
- private(set) var minimumUpdateDistanceInMeters: Double?
40
-
41
- public init(enableHighAccuracy: Bool, minimumUpdateDistanceInMeters: Double? = nil) {
42
- self.enableHighAccuracy = enableHighAccuracy
43
- self.minimumUpdateDistanceInMeters = minimumUpdateDistanceInMeters
44
- }
45
- }
@@ -1,152 +0,0 @@
1
- import Combine
2
- import CoreLocation
3
-
4
- public typealias IONGLOCService = IONGLOCServicesChecker & IONGLOCAuthorisationHandler & IONGLOCSingleLocationHandler & IONGLOCMonitorLocationHandler
5
-
6
- public struct IONGLOCServicesValidator: IONGLOCServicesChecker {
7
- public init() {}
8
-
9
- public func areLocationServicesEnabled() -> Bool {
10
- CLLocationManager.locationServicesEnabled()
11
- }
12
- }
13
-
14
- public class IONGLOCManagerWrapper: NSObject, IONGLOCService {
15
- @Published public var authorisationStatus: IONGLOCAuthorisation
16
- public var authorisationStatusPublisher: Published<IONGLOCAuthorisation>.Publisher { $authorisationStatus }
17
-
18
- @Published public var currentLocation: IONGLOCPositionModel?
19
- private var timeoutCancellable: AnyCancellable?
20
- public var currentLocationPublisher: AnyPublisher<IONGLOCPositionModel, IONGLOCLocationError> {
21
- Publishers.Merge($currentLocation, currentLocationForceSubject)
22
- .dropFirst() // ignore the first value as it's the one set on the constructor.
23
- .tryMap { location in
24
- guard let location else { throw IONGLOCLocationError.locationUnavailable }
25
- return location
26
- }
27
- .mapError { $0 as? IONGLOCLocationError ?? .other($0) }
28
- .eraseToAnyPublisher()
29
- }
30
-
31
- public var locationTimeoutPublisher: AnyPublisher<IONGLOCLocationError, Never> {
32
- locationTimeoutSubject.eraseToAnyPublisher()
33
- }
34
-
35
- private let currentLocationForceSubject = PassthroughSubject<IONGLOCPositionModel?, Never>()
36
- private let locationTimeoutSubject = PassthroughSubject<IONGLOCLocationError, Never>()
37
-
38
- private let locationManager: CLLocationManager
39
- private let servicesChecker: IONGLOCServicesChecker
40
-
41
- private var isMonitoringLocation = false
42
-
43
- // Flag used to indicate that the location request has timed out.
44
- // When `true`, the wrapper ignores any location updates received from CLLocationManager.
45
- // This prevents "stale" or "ghost" events from being sent to subscribers after the timeout has occurred.
46
- private var timeoutTriggered = false
47
-
48
- public init(locationManager: CLLocationManager = .init(), servicesChecker: IONGLOCServicesChecker = IONGLOCServicesValidator()) {
49
- self.locationManager = locationManager
50
- self.servicesChecker = servicesChecker
51
- self.authorisationStatus = locationManager.currentAuthorisationValue
52
-
53
- super.init()
54
- locationManager.delegate = self
55
- }
56
-
57
- public func requestAuthorisation(withType authorisationType: IONGLOCAuthorisationRequestType) {
58
- authorisationType.requestAuthorization(using: locationManager)
59
- }
60
-
61
- public func startMonitoringLocation(options: IONGLOCRequestOptionsModel) {
62
- timeoutTriggered = false
63
- isMonitoringLocation = true
64
- locationManager.startUpdatingLocation()
65
- self.startTimer(timeout: options.timeout)
66
- }
67
-
68
- public func startMonitoringLocation() {
69
- guard !timeoutTriggered else {
70
- return
71
- }
72
-
73
- isMonitoringLocation = true
74
- locationManager.startUpdatingLocation()
75
- }
76
-
77
- public func stopMonitoringLocation() {
78
- isMonitoringLocation = false
79
- locationManager.stopUpdatingLocation()
80
- }
81
-
82
- public func requestSingleLocation(options: IONGLOCRequestOptionsModel) {
83
- timeoutTriggered = false
84
- // If monitoring is active meaning the location service is already running
85
- // and calling .requestLocation() will not trigger a new location update,
86
- // we can just return the current location.
87
- if isMonitoringLocation, let location = currentLocation {
88
- currentLocationForceSubject.send(location)
89
- return
90
- }
91
-
92
- self.locationManager.requestLocation()
93
- self.startTimer(timeout: options.timeout)
94
- }
95
-
96
- private func startTimer(timeout: Int) {
97
- timeoutCancellable?.cancel()
98
- timeoutCancellable = nil
99
- timeoutCancellable = Just(())
100
- .delay(for: .milliseconds(timeout), scheduler: DispatchQueue.main)
101
- .sink { [weak self] _ in
102
- guard let self = self else { return }
103
- self.timeoutTriggered = true
104
- self.locationTimeoutSubject.send(.timeout)
105
-
106
- if self.isMonitoringLocation {
107
- self.isMonitoringLocation = false
108
- self.stopMonitoringLocation()
109
- }
110
-
111
- self.timeoutCancellable?.cancel()
112
- self.timeoutCancellable = nil
113
- }
114
- }
115
-
116
- public func updateConfiguration(_ configuration: IONGLOCConfigurationModel) {
117
- locationManager.desiredAccuracy = configuration.enableHighAccuracy ? kCLLocationAccuracyBest : kCLLocationAccuracyThreeKilometers
118
- configuration.minimumUpdateDistanceInMeters.map {
119
- locationManager.distanceFilter = $0
120
- }
121
- }
122
-
123
- public func areLocationServicesEnabled() -> Bool {
124
- servicesChecker.areLocationServicesEnabled()
125
- }
126
- }
127
-
128
- extension IONGLOCManagerWrapper: CLLocationManagerDelegate {
129
- public func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
130
- authorisationStatus = manager.currentAuthorisationValue
131
- }
132
-
133
- public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
134
- guard !timeoutTriggered else {
135
- return
136
- }
137
-
138
- timeoutCancellable?.cancel()
139
- timeoutCancellable = nil
140
- guard let latestLocation = locations.last else {
141
- currentLocation = nil
142
- return
143
- }
144
- currentLocation = IONGLOCPositionModel.create(from: latestLocation)
145
- }
146
-
147
- public func locationManager(_ manager: CLLocationManager, didFailWithError error: any Error) {
148
- timeoutCancellable?.cancel()
149
- timeoutCancellable = nil
150
- currentLocation = nil
151
- }
152
- }