@capacitor/geolocation 7.1.0-dev.2 → 7.1.1-pr.25

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.
package/Package.swift CHANGED
@@ -10,7 +10,7 @@ let package = Package(
10
10
  targets: ["GeolocationPlugin"])
11
11
  ],
12
12
  dependencies: [
13
- .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", branch: "main")
13
+ .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.0.0")
14
14
  ],
15
15
  targets: [
16
16
  .binaryTarget(
package/README.md CHANGED
@@ -48,7 +48,7 @@ Read about [Setting Permissions](https://capacitorjs.com/docs/android/configurat
48
48
 
49
49
  </docgen-index>
50
50
 
51
- For list of error codes, see [Errors](#Errors)
51
+ For list of error codes, see [Errors](#errors)
52
52
 
53
53
  <docgen-api>
54
54
  <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
@@ -2,6 +2,7 @@ import Capacitor
2
2
  import IONGeolocationLib
3
3
 
4
4
  private enum GeolocationCallbackType {
5
+ case requestPermissions
5
6
  case location
6
7
  case watch
7
8
 
@@ -10,7 +11,7 @@ private enum GeolocationCallbackType {
10
11
  }
11
12
 
12
13
  var shouldClearAfterSending: Bool {
13
- self == .location
14
+ self == .location || self == .requestPermissions
14
15
  }
15
16
  }
16
17
 
@@ -20,23 +21,34 @@ private struct GeolocationCallbackGroup {
20
21
  }
21
22
 
22
23
  final class GeolocationCallbackManager {
24
+ private(set) var requestPermissionsCallbacks: [CAPPluginCall]
23
25
  private(set) var locationCallbacks: [CAPPluginCall]
24
26
  private(set) var watchCallbacks: [String: CAPPluginCall]
25
27
  private let capacitorBridge: CAPBridgeProtocol?
26
28
 
27
29
  private var allCallbackGroups: [GeolocationCallbackGroup] {
28
30
  [
31
+ .init(ids: requestPermissionsCallbacks, type: .requestPermissions),
29
32
  .init(ids: locationCallbacks, type: .location),
30
33
  .init(ids: Array(watchCallbacks.values), type: .watch)
31
34
  ]
32
35
  }
36
+ private var requestPermissionsCallbackGroup: GeolocationCallbackGroup? {
37
+ allCallbackGroups.first { $0.type == .requestPermissions }
38
+ }
33
39
 
34
40
  init(capacitorBridge: CAPBridgeProtocol?) {
35
41
  self.capacitorBridge = capacitorBridge
42
+ self.requestPermissionsCallbacks = []
36
43
  self.locationCallbacks = []
37
44
  self.watchCallbacks = [:]
38
45
  }
39
46
 
47
+ func addRequestPermissionsCallback(capacitorCall call: CAPPluginCall) {
48
+ capacitorBridge?.saveCall(call)
49
+ requestPermissionsCallbacks.append(call)
50
+ }
51
+
40
52
  func addLocationCallback(capacitorCall call: CAPPluginCall) {
41
53
  capacitorBridge?.saveCall(call)
42
54
  locationCallbacks.append(call)
@@ -47,6 +59,13 @@ final class GeolocationCallbackManager {
47
59
  watchCallbacks[watchId] = call
48
60
  }
49
61
 
62
+ func clearRequestPermissionsCallbacks() {
63
+ requestPermissionsCallbacks.forEach {
64
+ capacitorBridge?.releaseCall($0)
65
+ }
66
+ requestPermissionsCallbacks.removeAll()
67
+ }
68
+
50
69
  func clearWatchCallbackIfExists(_ watchId: String) {
51
70
  if let callbackToRemove = watchCallbacks[watchId] {
52
71
  capacitorBridge?.releaseCall(callbackToRemove)
@@ -69,10 +88,25 @@ final class GeolocationCallbackManager {
69
88
  call.resolve(data)
70
89
  }
71
90
 
91
+ func sendRequestPermissionsSuccess(_ permissionsResult: String) {
92
+ if let group = requestPermissionsCallbackGroup {
93
+ let data = [
94
+ Constants.AuthorisationStatus.ResultKey.location: permissionsResult,
95
+ Constants.AuthorisationStatus.ResultKey.coarseLocation: permissionsResult
96
+ ]
97
+ send(.success(data), to: group)
98
+ }
99
+ }
100
+
72
101
  func sendSuccess(with position: IONGLOCPositionModel) {
73
102
  createPluginResult(status: .success(position.toJSObject()))
74
103
  }
75
104
 
105
+ func sendError(_ call: CAPPluginCall, error: GeolocationError) {
106
+ let errorModel = error.toCodeMessagePair()
107
+ call.reject(errorModel.1, errorModel.0)
108
+ }
109
+
76
110
  func sendError(_ error: GeolocationError) {
77
111
  createPluginResult(status: .error(error.toCodeMessagePair()))
78
112
  }
@@ -87,6 +121,7 @@ private enum CallResultStatus {
87
121
  }
88
122
 
89
123
  private extension GeolocationCallbackManager {
124
+
90
125
  func createPluginResult(status: CallResultStatus) {
91
126
  allCallbackGroups.forEach {
92
127
  send(status, to: $0)
@@ -112,6 +147,8 @@ private extension GeolocationCallbackManager {
112
147
  func clearCallbacks(for type: GeolocationCallbackType) {
113
148
  if case .location = type {
114
149
  clearLocationCallbacks()
150
+ } else if case .requestPermissions = type {
151
+ clearRequestPermissionsCallbacks()
115
152
  }
116
153
  }
117
154
  }
@@ -18,7 +18,8 @@ public class GeolocationPlugin: CAPPlugin, CAPBridgedPlugin {
18
18
  private var locationService: (any IONGLOCService)?
19
19
  private var cancellables = Set<AnyCancellable>()
20
20
  private var callbackManager: GeolocationCallbackManager?
21
- private var isInitialised: Bool = false
21
+ private var statusInitialized = false
22
+ private var locationInitialized: Bool = false
22
23
 
23
24
  override public func load() {
24
25
  self.locationService = IONGLOCManagerWrapper()
@@ -53,8 +54,8 @@ public class GeolocationPlugin: CAPPlugin, CAPBridgedPlugin {
53
54
  callbackManager?.sendSuccess(call)
54
55
  }
55
56
 
56
- override public func checkPermissions(_ call: CAPPluginCall) {
57
- checkIfLocationServicesAreEnabled()
57
+ @objc override public func checkPermissions(_ call: CAPPluginCall) {
58
+ guard checkIfLocationServicesAreEnabled(call) else { return }
58
59
 
59
60
  let status = switch locationService?.authorisationStatus {
60
61
  case .restricted, .denied: Constants.AuthorisationStatus.Status.denied
@@ -69,11 +70,12 @@ public class GeolocationPlugin: CAPPlugin, CAPBridgedPlugin {
69
70
  callbackManager?.sendSuccess(call, with: callResultData)
70
71
  }
71
72
 
72
- override public func requestPermissions(_ call: CAPPluginCall) {
73
- checkIfLocationServicesAreEnabled()
73
+ @objc override public func requestPermissions(_ call: CAPPluginCall) {
74
+ guard checkIfLocationServicesAreEnabled(call) else { return }
74
75
 
75
76
  if locationService?.authorisationStatus == .notDetermined {
76
77
  shouldSetupBindings()
78
+ callbackManager?.addRequestPermissionsCallback(capacitorCall: call)
77
79
  } else {
78
80
  checkPermissions(call)
79
81
  }
@@ -82,33 +84,40 @@ public class GeolocationPlugin: CAPPlugin, CAPBridgedPlugin {
82
84
 
83
85
  private extension GeolocationPlugin {
84
86
  func shouldSetupBindings() {
85
- guard !isInitialised else { return }
86
- isInitialised = true
87
- setupBindings()
87
+ bindauthorisationStatusPublisher()
88
+ bindLocationPublisher()
88
89
  }
89
90
 
90
- func setupBindings() {
91
+ func bindauthorisationStatusPublisher() {
92
+ guard !statusInitialized else { return }
93
+ statusInitialized = true
91
94
  locationService?.authorisationStatusPublisher
92
95
  .sink(receiveValue: { [weak self] status in
93
96
  guard let self else { return }
94
97
 
95
98
  switch status {
96
99
  case .denied:
97
- self.callbackManager?.sendError(.permissionDenied)
100
+ self.onLocationPermissionNotGranted(error: .permissionDenied)
98
101
  case .notDetermined:
99
102
  self.requestLocationAuthorisation(type: .whenInUse)
100
103
  case .restricted:
101
- self.callbackManager?.sendError(.permissionRestricted)
104
+ self.onLocationPermissionNotGranted(error: .permissionRestricted)
102
105
  case .authorisedAlways, .authorisedWhenInUse:
103
- self.requestLocation()
106
+ self.onLocationPermissionGranted()
104
107
  @unknown default: break
105
108
  }
106
109
  })
107
110
  .store(in: &cancellables)
111
+ }
108
112
 
113
+ func bindLocationPublisher() {
114
+ guard !locationInitialized else { return }
115
+ locationInitialized = true
109
116
  locationService?.currentLocationPublisher
110
117
  .sink(receiveCompletion: { [weak self] completion in
111
118
  if case .failure(let error) = completion {
119
+ // publisher should be re-observed in the next plugin call
120
+ self?.locationInitialized = false
112
121
  print("An error was found while retrieving the location: \(error)")
113
122
  self?.callbackManager?.sendError(.positionUnavailable)
114
123
  }
@@ -120,23 +129,41 @@ private extension GeolocationPlugin {
120
129
 
121
130
  func requestLocationAuthorisation(type requestType: IONGLOCAuthorisationRequestType) {
122
131
  DispatchQueue.global(qos: .background).async {
123
- self.checkIfLocationServicesAreEnabled()
132
+ guard self.checkIfLocationServicesAreEnabled() else { return }
124
133
  self.locationService?.requestAuthorisation(withType: requestType)
125
134
  }
126
135
  }
127
136
 
128
- func checkIfLocationServicesAreEnabled() {
129
- guard locationService?.areLocationServicesEnabled() ?? false else {
130
- callbackManager?.sendError(.locationServicesDisabled)
131
- return
137
+ func checkIfLocationServicesAreEnabled(_ call: CAPPluginCall? = nil) -> Bool {
138
+ guard locationService?.areLocationServicesEnabled() == true else {
139
+ call.map { callbackManager?.sendError($0, error: .locationServicesDisabled) }
140
+ ?? callbackManager?.sendError(.locationServicesDisabled)
141
+ return false
142
+ }
143
+ return true
144
+ }
145
+
146
+ func onLocationPermissionNotGranted(error: GeolocationError) {
147
+ let shouldNotifyRequestPermissionsResult = callbackManager?.requestPermissionsCallbacks.isEmpty == false
148
+ let shouldNotifyPermissionError = callbackManager?.locationCallbacks.isEmpty == false || callbackManager?.watchCallbacks.isEmpty == false
149
+
150
+ if shouldNotifyRequestPermissionsResult {
151
+ self.callbackManager?.sendRequestPermissionsSuccess(Constants.AuthorisationStatus.Status.denied)
152
+ }
153
+ if shouldNotifyPermissionError {
154
+ self.callbackManager?.sendError(error)
132
155
  }
133
156
  }
134
157
 
135
- func requestLocation() {
136
- // should request if callbacks exist and are not empty
158
+ func onLocationPermissionGranted() {
159
+ let shouldNotifyPermissionGranted = callbackManager?.requestPermissionsCallbacks.isEmpty == false
160
+ // should request location if callbacks below exist and are not empty
137
161
  let shouldRequestCurrentPosition = callbackManager?.locationCallbacks.isEmpty == false
138
162
  let shouldRequestLocationMonitoring = callbackManager?.watchCallbacks.isEmpty == false
139
163
 
164
+ if shouldNotifyPermissionGranted {
165
+ callbackManager?.sendRequestPermissionsSuccess(Constants.AuthorisationStatus.Status.granted)
166
+ }
140
167
  if shouldRequestCurrentPosition {
141
168
  locationService?.requestSingleLocation()
142
169
  }
@@ -156,7 +183,7 @@ private extension GeolocationPlugin {
156
183
  }
157
184
 
158
185
  switch locationService?.authorisationStatus {
159
- case .authorisedAlways, .authorisedWhenInUse: requestLocation()
186
+ case .authorisedAlways, .authorisedWhenInUse: onLocationPermissionGranted()
160
187
  case .denied: callbackManager?.sendError(.permissionDenied)
161
188
  case .restricted: callbackManager?.sendError(.permissionRestricted)
162
189
  default: break
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capacitor/geolocation",
3
- "version": "7.1.0-dev.2",
4
- "description": "Geolocation plugin for Capacitor",
3
+ "version": "7.1.1-pr.25",
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",
7
7
  "types": "dist/esm/index.d.ts",
@@ -86,4 +86,4 @@
86
86
  "src": "android"
87
87
  }
88
88
  }
89
- }
89
+ }