Skip to content

Commit 2586a9e

Browse files
fix(ios): resolving requestPermissions (#16)
1 parent 4ebf2b4 commit 2586a9e

File tree

5 files changed

+9718
-908
lines changed

5 files changed

+9718
-908
lines changed

packages/capacitor-plugin/ios/Sources/GeolocationPlugin/GeolocationCallbackManager.swift

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Capacitor
22
import IONGeolocationLib
33

44
private enum GeolocationCallbackType {
5+
case requestPermissions
56
case location
67
case watch
78

@@ -10,7 +11,7 @@ private enum GeolocationCallbackType {
1011
}
1112

1213
var shouldClearAfterSending: Bool {
13-
self == .location
14+
self == .location || self == .requestPermissions
1415
}
1516
}
1617

@@ -20,23 +21,34 @@ private struct GeolocationCallbackGroup {
2021
}
2122

2223
final class GeolocationCallbackManager {
24+
private(set) var requestPermissionsCallbacks: [CAPPluginCall]
2325
private(set) var locationCallbacks: [CAPPluginCall]
2426
private(set) var watchCallbacks: [String: CAPPluginCall]
2527
private let capacitorBridge: CAPBridgeProtocol?
2628

2729
private var allCallbackGroups: [GeolocationCallbackGroup] {
2830
[
31+
.init(ids: requestPermissionsCallbacks, type: .requestPermissions),
2932
.init(ids: locationCallbacks, type: .location),
3033
.init(ids: Array(watchCallbacks.values), type: .watch)
3134
]
3235
}
36+
private var requestPermissionsCallbackGroup: GeolocationCallbackGroup? {
37+
allCallbackGroups.first { $0.type == .requestPermissions }
38+
}
3339

3440
init(capacitorBridge: CAPBridgeProtocol?) {
3541
self.capacitorBridge = capacitorBridge
42+
self.requestPermissionsCallbacks = []
3643
self.locationCallbacks = []
3744
self.watchCallbacks = [:]
3845
}
3946

47+
func addRequestPermissionsCallback(capacitorCall call: CAPPluginCall) {
48+
capacitorBridge?.saveCall(call)
49+
requestPermissionsCallbacks.append(call)
50+
}
51+
4052
func addLocationCallback(capacitorCall call: CAPPluginCall) {
4153
capacitorBridge?.saveCall(call)
4254
locationCallbacks.append(call)
@@ -47,6 +59,13 @@ final class GeolocationCallbackManager {
4759
watchCallbacks[watchId] = call
4860
}
4961

62+
func clearRequestPermissionsCallbacks() {
63+
requestPermissionsCallbacks.forEach {
64+
capacitorBridge?.releaseCall($0)
65+
}
66+
requestPermissionsCallbacks.removeAll()
67+
}
68+
5069
func clearWatchCallbackIfExists(_ watchId: String) {
5170
if let callbackToRemove = watchCallbacks[watchId] {
5271
capacitorBridge?.releaseCall(callbackToRemove)
@@ -69,10 +88,25 @@ final class GeolocationCallbackManager {
6988
call.resolve(data)
7089
}
7190

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+
72101
func sendSuccess(with position: IONGLOCPositionModel) {
73102
createPluginResult(status: .success(position.toJSObject()))
74103
}
75104

105+
func sendError(_ call: CAPPluginCall, error: GeolocationError) {
106+
let errorModel = error.toCodeMessagePair()
107+
call.reject(errorModel.1, errorModel.0)
108+
}
109+
76110
func sendError(_ error: GeolocationError) {
77111
createPluginResult(status: .error(error.toCodeMessagePair()))
78112
}
@@ -87,6 +121,7 @@ private enum CallResultStatus {
87121
}
88122

89123
private extension GeolocationCallbackManager {
124+
90125
func createPluginResult(status: CallResultStatus) {
91126
allCallbackGroups.forEach {
92127
send(status, to: $0)
@@ -112,6 +147,8 @@ private extension GeolocationCallbackManager {
112147
func clearCallbacks(for type: GeolocationCallbackType) {
113148
if case .location = type {
114149
clearLocationCallbacks()
150+
} else if case .requestPermissions = type {
151+
clearRequestPermissionsCallbacks()
115152
}
116153
}
117154
}

packages/capacitor-plugin/ios/Sources/GeolocationPlugin/GeolocationPlugin.swift

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ public class GeolocationPlugin: CAPPlugin, CAPBridgedPlugin {
5353
callbackManager?.sendSuccess(call)
5454
}
5555

56-
override public func checkPermissions(_ call: CAPPluginCall) {
57-
checkIfLocationServicesAreEnabled()
56+
@objc override public func checkPermissions(_ call: CAPPluginCall) {
57+
guard checkIfLocationServicesAreEnabled(call) else { return }
5858

5959
let status = switch locationService?.authorisationStatus {
6060
case .restricted, .denied: Constants.AuthorisationStatus.Status.denied
@@ -69,11 +69,12 @@ public class GeolocationPlugin: CAPPlugin, CAPBridgedPlugin {
6969
callbackManager?.sendSuccess(call, with: callResultData)
7070
}
7171

72-
override public func requestPermissions(_ call: CAPPluginCall) {
73-
checkIfLocationServicesAreEnabled()
72+
@objc override public func requestPermissions(_ call: CAPPluginCall) {
73+
guard checkIfLocationServicesAreEnabled(call) else { return }
7474

7575
if locationService?.authorisationStatus == .notDetermined {
7676
shouldSetupBindings()
77+
callbackManager?.addRequestPermissionsCallback(capacitorCall: call)
7778
} else {
7879
checkPermissions(call)
7980
}
@@ -94,13 +95,13 @@ private extension GeolocationPlugin {
9495

9596
switch status {
9697
case .denied:
97-
self.callbackManager?.sendError(.permissionDenied)
98+
self.onLocationPermissionNotGranted(error: .permissionDenied)
9899
case .notDetermined:
99100
self.requestLocationAuthorisation(type: .whenInUse)
100101
case .restricted:
101-
self.callbackManager?.sendError(.permissionRestricted)
102+
self.onLocationPermissionNotGranted(error: .permissionRestricted)
102103
case .authorisedAlways, .authorisedWhenInUse:
103-
self.requestLocation()
104+
self.onLocationPermissionGranted()
104105
@unknown default: break
105106
}
106107
})
@@ -120,23 +121,41 @@ private extension GeolocationPlugin {
120121

121122
func requestLocationAuthorisation(type requestType: IONGLOCAuthorisationRequestType) {
122123
DispatchQueue.global(qos: .background).async {
123-
self.checkIfLocationServicesAreEnabled()
124+
guard self.checkIfLocationServicesAreEnabled() else { return }
124125
self.locationService?.requestAuthorisation(withType: requestType)
125126
}
126127
}
127128

128-
func checkIfLocationServicesAreEnabled() {
129-
guard locationService?.areLocationServicesEnabled() ?? false else {
130-
callbackManager?.sendError(.locationServicesDisabled)
131-
return
129+
func checkIfLocationServicesAreEnabled(_ call: CAPPluginCall? = nil) -> Bool {
130+
guard locationService?.areLocationServicesEnabled() == true else {
131+
call.map { callbackManager?.sendError($0, error: .locationServicesDisabled) }
132+
?? callbackManager?.sendError(.locationServicesDisabled)
133+
return false
134+
}
135+
return true
136+
}
137+
138+
func onLocationPermissionNotGranted(error: GeolocationError) {
139+
let shouldNotifyRequestPermissionsResult = callbackManager?.requestPermissionsCallbacks.isEmpty == false
140+
let shouldNotifyPermissionError = callbackManager?.locationCallbacks.isEmpty == false || callbackManager?.watchCallbacks.isEmpty == false
141+
142+
if shouldNotifyRequestPermissionsResult {
143+
self.callbackManager?.sendRequestPermissionsSuccess(Constants.AuthorisationStatus.Status.denied)
144+
}
145+
if shouldNotifyPermissionError {
146+
self.callbackManager?.sendError(error)
132147
}
133148
}
134149

135-
func requestLocation() {
136-
// should request if callbacks exist and are not empty
150+
func onLocationPermissionGranted() {
151+
let shouldNotifyPermissionGranted = callbackManager?.requestPermissionsCallbacks.isEmpty == false
152+
// should request location if callbacks below exist and are not empty
137153
let shouldRequestCurrentPosition = callbackManager?.locationCallbacks.isEmpty == false
138154
let shouldRequestLocationMonitoring = callbackManager?.watchCallbacks.isEmpty == false
139155

156+
if shouldNotifyPermissionGranted {
157+
callbackManager?.sendRequestPermissionsSuccess(Constants.AuthorisationStatus.Status.granted)
158+
}
140159
if shouldRequestCurrentPosition {
141160
locationService?.requestSingleLocation()
142161
}
@@ -156,7 +175,7 @@ private extension GeolocationPlugin {
156175
}
157176

158177
switch locationService?.authorisationStatus {
159-
case .authorisedAlways, .authorisedWhenInUse: requestLocation()
178+
case .authorisedAlways, .authorisedWhenInUse: onLocationPermissionGranted()
160179
case .denied: callbackManager?.sendError(.permissionDenied)
161180
case .restricted: callbackManager?.sendError(.permissionRestricted)
162181
default: break

packages/example-app-capacitor/ios/App/Podfile.lock

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
PODS:
2-
- Capacitor (7.0.0-rc.0):
2+
- Capacitor (7.0.1):
33
- CapacitorCordova
4-
- CapacitorCamera (7.0.0-alpha.2):
4+
- CapacitorCamera (7.0.0):
55
- Capacitor
6-
- CapacitorCordova (7.0.0-rc.0)
7-
- CapacitorGeolocation (7.0.0-alpha.2):
6+
- CapacitorCordova (7.0.1)
7+
- CapacitorGeolocation (7.1.0):
88
- Capacitor
99
- IONGeolocationLib (~> 1.0)
10-
- CapacitorSplashScreen (7.0.0-alpha.2):
10+
- CapacitorSplashScreen (7.0.0):
1111
- Capacitor
1212
- IONGeolocationLib (1.0.0)
1313

@@ -35,11 +35,11 @@ EXTERNAL SOURCES:
3535
:path: "../../node_modules/@capacitor/splash-screen"
3636

3737
SPEC CHECKSUMS:
38-
Capacitor: e79eb426d47f13ee0e2fdaff9ef0e9990db34a48
39-
CapacitorCamera: ad97105da555e693f9885aaab084d205f8d82366
40-
CapacitorCordova: 8f4f6826f0b40f7b506eb13b832039b7140a88b4
41-
CapacitorGeolocation: dde03dcfdc26a83c0c837eb56bf5852dac3bc04e
42-
CapacitorSplashScreen: f612f95daee8566768daf86646b97d4dcac01240
38+
Capacitor: 23fff43571a4d1e3ee7d67b5a3588c6e757c2913
39+
CapacitorCamera: 777ddf61d727754fcda0b92303ae09ea3765d7b7
40+
CapacitorCordova: 63d476958d5022d76f197031e8b7ea3519988c64
41+
CapacitorGeolocation: c24f77edcc58510fb87418754407e448fc48b9b5
42+
CapacitorSplashScreen: f4e58cc02aafd91c7cbaf32a3d1b44d02a115125
4343
IONGeolocationLib: 81f33f88d025846946de2cf63b0c7628e7c6bc9d
4444

4545
PODFILE CHECKSUM: 6e3f0881e9bf33b13c7f481b07ee65b5c9321cb0

0 commit comments

Comments
 (0)