@tokamakdev/plugin-location 0.1.0-beta.54 → 0.1.0-beta.56

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.
@@ -91,14 +91,7 @@ class TokamakLocationPlugin(
91
91
  PackageManager.PERMISSION_GRANTED
92
92
 
93
93
  private fun currentPosition(reply: TokamakPluginReply) {
94
- val provider = runCatching(::provider).getOrElse {
95
- reply(locationFailure(it, "Location is unavailable"))
96
- return
97
- }
98
- if (provider == null) {
99
- reply(unavailable("No location provider is available"))
100
- return
101
- }
94
+ val provider = availableProvider(reply) ?: return
102
95
  runCatching {
103
96
  manager.getCurrentLocation(
104
97
  provider,
@@ -108,18 +101,11 @@ class TokamakLocationPlugin(
108
101
  if (location == null) reply(unavailable("Location is unavailable"))
109
102
  else reply(Result.success(position(location)))
110
103
  }
111
- }.onFailure { reply(locationFailure(it, "Location is unavailable")) }
104
+ }.onFailure { reply(locationFailure(it)) }
112
105
  }
113
106
 
114
107
  private fun watchPosition(reply: TokamakPluginReply): () -> Unit {
115
- val provider = runCatching(::provider).getOrElse {
116
- reply(locationFailure(it, "Location is unavailable"))
117
- return {}
118
- }
119
- if (provider == null) {
120
- reply(unavailable("No location provider is available"))
121
- return {}
122
- }
108
+ val provider = availableProvider(reply) ?: return {}
123
109
  val listener = object : LocationListener {
124
110
  override fun onLocationChanged(location: Location) {
125
111
  reply(Result.success(position(location)))
@@ -131,16 +117,25 @@ class TokamakLocationPlugin(
131
117
 
132
118
  override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) = Unit
133
119
  }
134
- val started = runCatching {
120
+ runCatching {
135
121
  manager.requestLocationUpdates(provider, 1000, 0F, listener, Looper.getMainLooper())
136
- }
137
- if (started.isFailure) {
138
- reply(locationFailure(started.exceptionOrNull(), "Location is unavailable"))
122
+ }.onFailure {
123
+ reply(locationFailure(it))
139
124
  return {}
140
125
  }
141
126
  return { manager.removeUpdates(listener) }
142
127
  }
143
128
 
129
+ /** The provider to use, or null once [reply] has the reason there is none. */
130
+ private fun availableProvider(reply: TokamakPluginReply): String? {
131
+ val provider = runCatching(::provider).getOrElse {
132
+ reply(locationFailure(it))
133
+ return null
134
+ }
135
+ if (provider == null) reply(unavailable("No location provider is available"))
136
+ return provider
137
+ }
138
+
144
139
  private fun provider(): String? =
145
140
  listOf(
146
141
  LocationManager.GPS_PROVIDER,
@@ -172,9 +167,9 @@ class TokamakLocationPlugin(
172
167
  private fun unavailable(message: String): Result<Any?> =
173
168
  Result.failure(TokamakPluginError("NotReadableError", message))
174
169
 
175
- private fun locationFailure(error: Throwable?, fallback: String): Result<Any?> =
170
+ private fun locationFailure(error: Throwable): Result<Any?> =
176
171
  if (error is SecurityException) permissionDenied()
177
- else unavailable(error?.message ?: fallback)
172
+ else unavailable(error.message ?: "Location is unavailable")
178
173
 
179
174
  private companion object {
180
175
  const val LOCATION_PERMISSION_REQUEST = 0xA771
@@ -6,6 +6,11 @@ final class TokamakLocationPlugin: NSObject, TokamakPlugin,
6
6
  {
7
7
  let id = "location"
8
8
 
9
+ private static let permissionDenied = TokamakPluginError(
10
+ name: "NotAllowedError",
11
+ message: "Location permission was denied"
12
+ )
13
+
9
14
  private let manager = CLLocationManager()
10
15
  private var current: [TokamakPluginReply] = []
11
16
  private var watchers: [UUID: TokamakPluginReply] = [:]
@@ -50,20 +55,7 @@ final class TokamakLocationPlugin: NSObject, TokamakPlugin,
50
55
  func locationManagerDidChangeAuthorization(
51
56
  _ manager: CLLocationManager
52
57
  ) {
53
- switch manager.authorizationStatus {
54
- case .authorizedAlways, .authorizedWhenInUse:
55
- manager.startUpdatingLocation()
56
- case .denied, .restricted:
57
- fail(
58
- TokamakPluginError(
59
- name: "NotAllowedError",
60
- message: "Location permission was denied"
61
- ))
62
- case .notDetermined:
63
- break
64
- @unknown default:
65
- fail(.notSupported("Location authorization is not supported"))
66
- }
58
+ startIfAuthorized(manager.authorizationStatus)
67
59
  }
68
60
 
69
61
  func locationManager(
@@ -71,16 +63,7 @@ final class TokamakLocationPlugin: NSObject, TokamakPlugin,
71
63
  didUpdateLocations locations: [CLLocation]
72
64
  ) {
73
65
  guard let location = locations.last else { return }
74
- let result = Result<Any?, TokamakPluginError>.success(position(location))
75
- let waiting = current
76
- current.removeAll()
77
- for reply in waiting {
78
- reply(result)
79
- }
80
- for reply in watchers.values {
81
- reply(result)
82
- }
83
- stopIfIdle()
66
+ deliver(.success(position(location)))
84
67
  }
85
68
 
86
69
  func locationManager(
@@ -98,40 +81,47 @@ final class TokamakLocationPlugin: NSObject, TokamakPlugin,
98
81
  fail(unavailable("Location services are disabled"))
99
82
  return
100
83
  }
101
- switch manager.authorizationStatus {
84
+ let status = manager.authorizationStatus
85
+ if status == .notDetermined {
86
+ manager.requestWhenInUseAuthorization()
87
+ } else {
88
+ startIfAuthorized(status)
89
+ }
90
+ }
91
+
92
+ /// Starts updates when `status` allows them and fails every request when it
93
+ /// forbids them.
94
+ private func startIfAuthorized(_ status: CLAuthorizationStatus) {
95
+ switch status {
102
96
  case .authorizedAlways, .authorizedWhenInUse:
103
97
  manager.startUpdatingLocation()
104
- case .notDetermined:
105
- manager.requestWhenInUseAuthorization()
106
98
  case .denied, .restricted:
107
- fail(
108
- TokamakPluginError(
109
- name: "NotAllowedError",
110
- message: "Location permission was denied"
111
- ))
99
+ fail(Self.permissionDenied)
100
+ case .notDetermined:
101
+ break
112
102
  @unknown default:
113
103
  fail(.notSupported("Location authorization is not supported"))
114
104
  }
115
105
  }
116
106
 
117
107
  private func fail(_ error: TokamakPluginError) {
118
- let result = Result<Any?, TokamakPluginError>.failure(error)
108
+ deliver(.failure(error))
109
+ }
110
+
111
+ /// Replies to the waiting requests and every watcher, then stops when none
112
+ /// remain.
113
+ private func deliver(_ result: Result<Any?, TokamakPluginError>) {
119
114
  let replies = current + Array(watchers.values)
120
115
  current.removeAll()
121
116
  for reply in replies {
122
117
  reply(result)
123
118
  }
124
- if watchers.isEmpty {
125
- manager.stopUpdatingLocation()
126
- }
119
+ stopIfIdle()
127
120
  }
128
121
 
129
122
  private func locationError(_ error: Error) -> TokamakPluginError {
130
123
  if (error as NSError).code == CLError.Code.denied.rawValue {
131
- return TokamakPluginError(
132
- name: "NotAllowedError",
133
- message: "Location permission was denied"
134
- )
124
+ return Self.permissionDenied
135
125
  }
136
126
  return unavailable(error.localizedDescription)
137
127
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokamakdev/plugin-location",
3
- "version": "0.1.0-beta.54",
3
+ "version": "0.1.0-beta.56",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/mantty/tokamak.git",
@@ -11,7 +11,7 @@
11
11
  ".": "./src/index.ts"
12
12
  },
13
13
  "dependencies": {
14
- "@tokamakdev/plugin": "0.1.0-beta.54"
14
+ "@tokamakdev/plugin": "0.1.0-beta.56"
15
15
  },
16
16
  "files": [
17
17
  "android",
package/src/index.ts CHANGED
@@ -25,19 +25,14 @@ class Location extends FrontendPlugin {
25
25
  }
26
26
 
27
27
  getCurrentPosition(): Promise<Position> {
28
- if (this.hasNativeTransport) {
29
- return this.call("getCurrentPosition");
30
- }
31
- return web.getCurrentPosition();
28
+ return this.hasNativeTransport ? this.call("getCurrentPosition") : web.getCurrentPosition();
32
29
  }
33
30
 
34
31
  watchPosition(next: PositionCallback, error: PositionErrorCallback): () => void {
35
- if (this.hasNativeTransport) {
36
- return this.listen("watchPosition", (position) => {
37
- next(position as Position);
38
- }, error);
39
- }
40
- return web.watchPosition(next, error);
32
+ if (!this.hasNativeTransport) return web.watchPosition(next, error);
33
+ return this.listen("watchPosition", (position) => {
34
+ next(position as Position);
35
+ }, error);
41
36
  }
42
37
  }
43
38