@wayq/beekon-rn 0.0.1 → 0.0.3

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.
Files changed (78) hide show
  1. package/BeekonRn.podspec +3 -3
  2. package/README.md +24 -30
  3. package/android/build.gradle +3 -3
  4. package/android/src/main/java/in/wayq/beekonrn/BeekonRnModule.kt +182 -0
  5. package/android/src/main/java/{com → in}/wayq/beekonrn/BeekonRnPackage.kt +1 -1
  6. package/ios/BeekonRn.h +5 -1
  7. package/ios/BeekonRn.mm +15 -25
  8. package/ios/BeekonRn.swift +96 -116
  9. package/ios/Frameworks/BeekonKit.xcframework/_CodeSignature/CodeDirectory +0 -0
  10. package/ios/Frameworks/BeekonKit.xcframework/_CodeSignature/CodeResources +105 -42
  11. package/ios/Frameworks/BeekonKit.xcframework/_CodeSignature/CodeSignature +0 -0
  12. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/BeekonKit +0 -0
  13. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Info.plist +0 -0
  14. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.abi.json +2427 -0
  15. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  16. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios.swiftinterface +85 -0
  17. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/PrivacyInfo.xcprivacy +1 -1
  18. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/_CodeSignature/CodeResources +36 -3
  19. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/BeekonKit +0 -0
  20. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Info.plist +0 -0
  21. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.abi.json +2427 -0
  22. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  23. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/arm64-apple-ios-simulator.swiftinterface +85 -0
  24. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.abi.json +2427 -0
  25. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  26. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Modules/BeekonKit.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +85 -0
  27. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/PrivacyInfo.xcprivacy +1 -1
  28. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/_CodeSignature/CodeResources +69 -3
  29. package/lib/module/NativeBeekonRn.js +2 -2
  30. package/lib/module/NativeBeekonRn.js.map +1 -1
  31. package/lib/module/beekon.js +50 -53
  32. package/lib/module/beekon.js.map +1 -1
  33. package/lib/module/index.js +1 -0
  34. package/lib/module/index.js.map +1 -1
  35. package/lib/module/internal/mappers.js +49 -21
  36. package/lib/module/internal/mappers.js.map +1 -1
  37. package/lib/module/types/config.js +0 -2
  38. package/lib/module/types/error.js +19 -0
  39. package/lib/module/types/error.js.map +1 -0
  40. package/lib/module/types/location.js +2 -0
  41. package/lib/module/types/{position.js.map → location.js.map} +1 -1
  42. package/lib/typescript/src/NativeBeekonRn.d.ts +22 -26
  43. package/lib/typescript/src/NativeBeekonRn.d.ts.map +1 -1
  44. package/lib/typescript/src/beekon.d.ts +29 -42
  45. package/lib/typescript/src/beekon.d.ts.map +1 -1
  46. package/lib/typescript/src/index.d.ts +3 -3
  47. package/lib/typescript/src/index.d.ts.map +1 -1
  48. package/lib/typescript/src/internal/mappers.d.ts +10 -3
  49. package/lib/typescript/src/internal/mappers.d.ts.map +1 -1
  50. package/lib/typescript/src/types/config.d.ts +23 -31
  51. package/lib/typescript/src/types/config.d.ts.map +1 -1
  52. package/lib/typescript/src/types/error.d.ts +14 -0
  53. package/lib/typescript/src/types/error.d.ts.map +1 -0
  54. package/lib/typescript/src/types/location.d.ts +26 -0
  55. package/lib/typescript/src/types/location.d.ts.map +1 -0
  56. package/lib/typescript/src/types/state.d.ts +9 -9
  57. package/lib/typescript/src/types/state.d.ts.map +1 -1
  58. package/package.json +2 -2
  59. package/scripts/fetch-beekonkit.sh +5 -2
  60. package/src/NativeBeekonRn.ts +22 -26
  61. package/src/beekon.ts +58 -56
  62. package/src/index.tsx +3 -3
  63. package/src/internal/mappers.ts +52 -18
  64. package/src/types/config.ts +23 -32
  65. package/src/types/error.ts +22 -0
  66. package/src/types/location.ts +25 -0
  67. package/src/types/state.ts +13 -7
  68. package/android/src/main/java/com/wayq/beekonrn/BeekonRnModule.kt +0 -233
  69. package/ios/Frameworks/BeekonKit.xcframework/_CodeSignature/CodeRequirements-1 +0 -0
  70. package/lib/module/types/position.js +0 -2
  71. package/lib/module/types/preset.js +0 -2
  72. package/lib/module/types/preset.js.map +0 -1
  73. package/lib/typescript/src/types/position.d.ts +0 -24
  74. package/lib/typescript/src/types/position.d.ts.map +0 -1
  75. package/lib/typescript/src/types/preset.d.ts +0 -12
  76. package/lib/typescript/src/types/preset.d.ts.map +0 -1
  77. package/src/types/position.ts +0 -23
  78. package/src/types/preset.ts +0 -11
package/BeekonRn.podspec CHANGED
@@ -10,9 +10,9 @@ Pod::Spec.new do |s|
10
10
  s.license = package["license"]
11
11
  s.authors = package["author"]
12
12
 
13
- # Match RN 0.85 default Podfile floor (15.1). Native BeekonKit's floor is
14
- # 15.0 so this is satisfied. Bump only if RN raises its default.
15
- s.platforms = { :ios => "15.1" }
13
+ # BeekonKit targets iOS 17.0 (uses CLLocationUpdate.liveUpdates). The
14
+ # consuming app must also target iOS 17.0 or higher.
15
+ s.platforms = { :ios => "17.0" }
16
16
  s.source = { :git => "https://github.com/wayqteam/beekon.git", :tag => "v#{s.version}" }
17
17
 
18
18
  s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
package/README.md CHANGED
@@ -2,19 +2,17 @@
2
2
 
3
3
  React Native binding for the [Beekon](https://github.com/wayqteam/beekon) location SDK.
4
4
 
5
- A thin pass-through over the native Android (`io.github.wayqteam:beekon`) and iOS (`BeekonKit`) libraries. The public TypeScript surface mirrors the Kotlin / Swift / Dart APIs in shape: `init / configure / start / stop`, callback-backed `state` and `positions` streams, and a `history(from, to)` query.
5
+ A thin pass-through over the native Android (`io.github.wayqteam:beekon`) and iOS (`BeekonKit`) libraries. The public TypeScript surface mirrors the Kotlin / Swift APIs in shape: `configure / start / stop`, callback-backed `state` and `locations` streams, and a `history(from, to)` query.
6
6
 
7
- Built on the React Native New Architecture (TurboModules + Codegen). The binding is a thin delegation layer — all logic, persistence, and OS integration lives natively. **Writes never cross into JavaScript**: in background the JS engine isn't guaranteed to be alive, so the native libraries own the persistence path end-to-end (same rule as the Flutter binding).
8
-
9
- See [`../docs/REQUIREMENTS.md`](../docs/REQUIREMENTS.md) for the full cross-platform spec.
7
+ Built on the React Native New Architecture (TurboModules + Codegen). The binding is a thin delegation layer — all logic, persistence, and OS integration lives natively. **Writes never cross into JavaScript**: in background the JS engine isn't guaranteed to be alive, so the native libraries own the persistence path end-to-end.
10
8
 
11
9
  ## Requirements
12
10
 
13
11
  | Area | Floor |
14
12
  |---|---|
15
13
  | React Native | 0.76+ (target 0.85) |
16
- | iOS | 15.1 |
17
- | Android | API 24 |
14
+ | iOS | 17.0 |
15
+ | Android | API 26 |
18
16
  | New Architecture | required (Old Arch is unsupported) |
19
17
 
20
18
  ## Install
@@ -63,22 +61,18 @@ The library does NOT request permissions itself — your app must. Use a library
63
61
  ## Usage
64
62
 
65
63
  ```ts
66
- import { Beekon, type BeekonState, type Position } from '@wayq/beekon-rn';
64
+ import { Beekon, type BeekonState, type Location } from '@wayq/beekon-rn';
67
65
 
68
- // Subscribe — returns an unsubscribe function.
66
+ // Subscribe — returns an unsubscribe function. State replays the latest value
67
+ // to new subscribers; locations is broadcast (no replay).
69
68
  const offState = Beekon.onState((s: BeekonState) => console.log('state', s));
70
- const offPos = Beekon.onPosition((p: Position) => console.log('pos', p));
71
-
72
- // Initialize once at startup.
73
- await Beekon.init();
69
+ const offLoc = Beekon.onLocation((l: Location) => console.log('location', l));
74
70
 
75
- // Configure (Android requires `androidNotification`; iOS ignores it).
71
+ // Configure. Defaults: 30 s / 100 m. Pass 0 to disable a gate.
76
72
  await Beekon.configure({
77
- preset: 'balanced', // or 'saver' / 'precision'
73
+ intervalSeconds: 10,
74
+ distanceMeters: 30,
78
75
  androidNotification: {
79
- channelId: 'beekon_tracking',
80
- channelName: 'Beekon location tracking',
81
- notificationId: 1001,
82
76
  title: 'Tracking',
83
77
  text: 'Recording your route',
84
78
  smallIconResName: 'ic_notification', // drawable in your app
@@ -89,33 +83,33 @@ await Beekon.start();
89
83
  // ... later
90
84
  await Beekon.stop();
91
85
 
92
- // Read past positions.
93
- const pts = await Beekon.history(new Date(Date.now() - 3600_000), new Date());
86
+ // Read past fixes.
87
+ const fixes = await Beekon.history(new Date(Date.now() - 3600_000), new Date());
94
88
 
95
89
  // Cleanup.
96
90
  offState();
97
- offPos();
91
+ offLoc();
98
92
  ```
99
93
 
100
94
  ## API
101
95
 
102
96
  | Method | Description |
103
97
  |---|---|
104
- | `Beekon.init()` | One-time initialization. Idempotent. |
105
- | `Beekon.configure(config)` | Set sampling / Android notification config. |
106
- | `Beekon.start()` | Begin tracking. State → `starting` `tracking`. |
107
- | `Beekon.stop()` | Stop tracking. Idempotent. State `stopped`. |
108
- | `Beekon.shutdown()` | Final teardown. Most apps don't need this. |
109
- | `Beekon.history(from, to)` | Read persisted positions in range. |
98
+ | `Beekon.configure(config)` | Set sampling thresholds. Optional. |
99
+ | `Beekon.start()` | Begin tracking. State `tracking`. |
100
+ | `Beekon.stop()` | Stop tracking. Idempotent. State → `stopped` (`reason: 'user'`). |
101
+ | `Beekon.history(from, to)` | Read persisted fixes in range. |
110
102
  | `Beekon.onState(cb)` | Subscribe to state. Returns unsubscribe fn. |
111
- | `Beekon.onPosition(cb)` | Subscribe to gated positions. Returns unsubscribe fn. |
103
+ | `Beekon.onLocation(cb)` | Subscribe to gated fixes. Returns unsubscribe fn. |
104
+
105
+ State is a discriminated union on `kind`: `'idle' | 'tracking' | 'stopped'`. The `'stopped'` variant carries a `reason: 'user' | 'permissionDenied' | 'locationServicesDisabled' | 'system'` (`'system'` is Android-only).
112
106
 
113
- Errors are thrown as `Error` instances with stable platform-agnostic codes:
114
- `NOT_INITIALISED`, `NOT_CONFIGURED`, `PERMISSION_DENIED`, `LOCATION_SERVICES_DISABLED` (iOS), `NO_GMS_AVAILABLE` (Android), `SERVICE_FAILED`, `INTERNAL_ERROR`.
107
+ Errors are thrown as `BeekonError` instances with `kind`:
108
+ `'permissionDenied'`, `'locationServicesDisabled'`, `'storageFailure'`.
115
109
 
116
110
  ## Storage and retention
117
111
 
118
- The native SDKs persist every gated position locally (Room on Android, GRDB on iOS) — JS is a passive reader. Retention: **TTL 7 days OR most recent 100 K rows**, whichever is smaller; auto-pruned on each write batch.
112
+ The native SDKs persist every gated fix locally (Room on Android, GRDB on iOS) — JS is a passive reader. Retention: **TTL 7 days OR most recent 100 K rows**, whichever is smaller; auto-pruned on each write batch.
119
113
 
120
114
  ## License
121
115
 
@@ -1,6 +1,6 @@
1
1
  buildscript {
2
2
  ext.BeekonRn = [
3
- kotlinVersion: "2.0.21",
3
+ kotlinVersion: "2.1.20",
4
4
  minSdkVersion: 24,
5
5
  compileSdkVersion: 36,
6
6
  targetSdkVersion: 36
@@ -33,7 +33,7 @@ apply plugin: "kotlin-android"
33
33
  apply plugin: "com.facebook.react"
34
34
 
35
35
  android {
36
- namespace "com.wayq.beekonrn"
36
+ namespace "in.wayq.beekonrn"
37
37
 
38
38
  compileSdkVersion getExtOrDefault("compileSdkVersion")
39
39
 
@@ -72,7 +72,7 @@ dependencies {
72
72
  // Native Beekon SDK — published from beekon-android/ via Maven Central.
73
73
  // Pinned exact in v0.x to avoid surprise breakage; loosen to a range when
74
74
  // the SDK reaches v1 stability.
75
- implementation "io.github.wayqteam:beekon:0.0.1"
75
+ implementation "io.github.wayqteam:beekon:0.0.3"
76
76
  // Kotlin coroutines — required for collecting Beekon's StateFlow/SharedFlow.
77
77
  // Beekon already depends on coroutines transitively, but declaring it here
78
78
  // makes the dependency intent explicit.
@@ -0,0 +1,182 @@
1
+ package `in`.wayq.beekonrn
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.Promise
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.bridge.ReadableMap
7
+ import com.facebook.react.bridge.WritableArray
8
+ import com.facebook.react.bridge.WritableMap
9
+ import `in`.wayq.beekon.Beekon
10
+ import `in`.wayq.beekon.BeekonConfig
11
+ import `in`.wayq.beekon.BeekonError
12
+ import `in`.wayq.beekon.BeekonState
13
+ import `in`.wayq.beekon.Location
14
+ import `in`.wayq.beekon.StopReason
15
+ import java.time.Instant
16
+ import kotlinx.coroutines.CoroutineScope
17
+ import kotlinx.coroutines.Dispatchers
18
+ import kotlinx.coroutines.Job
19
+ import kotlinx.coroutines.SupervisorJob
20
+ import kotlinx.coroutines.cancel
21
+ import kotlinx.coroutines.launch
22
+
23
+ class BeekonRnModule(private val reactContext: ReactApplicationContext) :
24
+ NativeBeekonRnSpec(reactContext) {
25
+
26
+ // Default dispatcher (not Main.immediate) — Codegen's emitOnX is thread-safe
27
+ // and marshals to JS internally, so collecting on Main buys nothing and
28
+ // risks jank if any mapper does work. SupervisorJob so a single failure
29
+ // doesn't tear down siblings.
30
+ private val scope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
31
+ private var stateJob: Job? = null
32
+ private var locationsJob: Job? = null
33
+
34
+ init {
35
+ // Beekon.initialize is idempotent and does not start tracking. Safe to call
36
+ // from module construction — the application context is already alive.
37
+ Beekon.initialize(reactContext.applicationContext)
38
+ stateJob = scope.launch {
39
+ Beekon.state.collect { s -> emitOnState(stateToWire(s)) }
40
+ }
41
+ locationsJob = scope.launch {
42
+ Beekon.locations.collect { loc -> emitOnLocation(locationToWire(loc)) }
43
+ }
44
+ }
45
+
46
+ override fun configure(config: ReadableMap, promise: Promise) {
47
+ scope.launch {
48
+ try {
49
+ Beekon.configure(wireToConfig(config))
50
+ promise.resolve(null)
51
+ } catch (t: Throwable) {
52
+ promise.reject(errorCode(t), t.message ?: "configure failed", t)
53
+ }
54
+ }
55
+ }
56
+
57
+ override fun start(promise: Promise) {
58
+ scope.launch {
59
+ try {
60
+ Beekon.start()
61
+ promise.resolve(null)
62
+ } catch (t: Throwable) {
63
+ promise.reject(errorCode(t), t.message ?: "start failed", t)
64
+ }
65
+ }
66
+ }
67
+
68
+ override fun stop(promise: Promise) {
69
+ scope.launch {
70
+ try {
71
+ Beekon.stop()
72
+ promise.resolve(null)
73
+ } catch (t: Throwable) {
74
+ promise.reject(errorCode(t), t.message ?: "stop failed", t)
75
+ }
76
+ }
77
+ }
78
+
79
+ override fun history(fromMs: Double, toMs: Double, promise: Promise) {
80
+ scope.launch {
81
+ try {
82
+ val from = Instant.ofEpochMilli(fromMs.toLong())
83
+ val to = Instant.ofEpochMilli(toMs.toLong())
84
+ val locations = Beekon.history(from, to)
85
+ val arr: WritableArray = Arguments.createArray()
86
+ for (loc in locations) arr.pushMap(locationToWire(loc))
87
+ promise.resolve(arr)
88
+ } catch (t: Throwable) {
89
+ promise.reject(errorCode(t), t.message ?: "history failed", t)
90
+ }
91
+ }
92
+ }
93
+
94
+ override fun invalidate() {
95
+ super.invalidate()
96
+ scope.cancel()
97
+ }
98
+
99
+ // ---------------------------------------------------------------------------
100
+ // Mappers (Wire ↔ Kotlin types)
101
+ // ---------------------------------------------------------------------------
102
+
103
+ private fun wireToConfig(map: ReadableMap): BeekonConfig {
104
+ val intervalSeconds = map.getDouble("intervalSeconds").toLong()
105
+ val distanceMeters = map.getDouble("distanceMeters")
106
+ val notification = map.getMap("androidNotification")
107
+ ?.let { wireToNotification(it) }
108
+ ?: BeekonConfig.Notification()
109
+ return BeekonConfig(
110
+ intervalSeconds = intervalSeconds,
111
+ distanceMeters = distanceMeters,
112
+ notification = notification,
113
+ )
114
+ }
115
+
116
+ private fun wireToNotification(map: ReadableMap): BeekonConfig.Notification {
117
+ val title = if (map.hasKey("title") && !map.isNull("title")) map.getString("title") else null
118
+ val text = if (map.hasKey("text") && !map.isNull("text")) map.getString("text") else null
119
+ val resName =
120
+ if (map.hasKey("smallIconResName") && !map.isNull("smallIconResName"))
121
+ map.getString("smallIconResName")
122
+ else null
123
+ val smallIcon: Int? = resName?.let {
124
+ val pkg = reactContext.packageName
125
+ val id = reactContext.resources.getIdentifier(it, "drawable", pkg)
126
+ if (id == 0) {
127
+ throw IllegalArgumentException("drawable resource '$it' not found in package '$pkg'")
128
+ }
129
+ id
130
+ }
131
+ return BeekonConfig.Notification(title = title, text = text, smallIcon = smallIcon)
132
+ }
133
+
134
+ private fun locationToWire(loc: Location): WritableMap {
135
+ val m = Arguments.createMap()
136
+ m.putDouble("lat", loc.lat)
137
+ m.putDouble("lng", loc.lng)
138
+ m.putDouble("timestampMs", loc.timestamp.toEpochMilli().toDouble())
139
+ putNullableDouble(m, "accuracy", loc.accuracy)
140
+ putNullableDouble(m, "speed", loc.speed)
141
+ putNullableDouble(m, "bearing", loc.bearing)
142
+ putNullableDouble(m, "altitude", loc.altitude)
143
+ return m
144
+ }
145
+
146
+ private fun putNullableDouble(map: WritableMap, key: String, value: Double?) {
147
+ if (value == null) map.putNull(key) else map.putDouble(key, value)
148
+ }
149
+
150
+ private fun stateToWire(s: BeekonState): WritableMap {
151
+ val m = Arguments.createMap()
152
+ when (s) {
153
+ BeekonState.Idle -> m.putString("type", "idle")
154
+ BeekonState.Tracking -> m.putString("type", "tracking")
155
+ is BeekonState.Stopped -> {
156
+ m.putString("type", "stopped")
157
+ m.putString("stopReason", stopReasonToWire(s.reason))
158
+ }
159
+ }
160
+ return m
161
+ }
162
+
163
+ private fun stopReasonToWire(r: StopReason): String = when (r) {
164
+ StopReason.User -> "user"
165
+ StopReason.PermissionDenied -> "permissionDenied"
166
+ StopReason.LocationServicesDisabled -> "locationServicesDisabled"
167
+ StopReason.System -> "system"
168
+ }
169
+
170
+ // Maps native error sealed types to stable JS-side codes. Same code strings
171
+ // on iOS so JS can switch on them platform-agnostically.
172
+ private fun errorCode(t: Throwable): String = when (t) {
173
+ is BeekonError.PermissionDenied -> "PERMISSION_DENIED"
174
+ is BeekonError.LocationServicesDisabled -> "LOCATION_SERVICES_DISABLED"
175
+ is BeekonError.StorageFailure -> "STORAGE_FAILURE"
176
+ else -> "INTERNAL_ERROR"
177
+ }
178
+
179
+ companion object {
180
+ const val NAME = NativeBeekonRnSpec.NAME
181
+ }
182
+ }
@@ -1,4 +1,4 @@
1
- package com.wayq.beekonrn
1
+ package `in`.wayq.beekonrn
2
2
 
3
3
  import com.facebook.react.BaseReactPackage
4
4
  import com.facebook.react.bridge.NativeModule
package/ios/BeekonRn.h CHANGED
@@ -1,5 +1,9 @@
1
1
  #import <BeekonRnSpec/BeekonRnSpec.h>
2
2
 
3
- @interface BeekonRn : NSObject <NativeBeekonRnSpec>
3
+ // Inherit from NativeBeekonRnSpecBase (codegen-provided) — it ships the
4
+ // concrete `emitOnState:` / `emitOnLocation:` implementations that bridge
5
+ // to JS via the EventEmitter callback. Conform to the protocol for the
6
+ // method-side TurboModule contract.
7
+ @interface BeekonRn : NativeBeekonRnSpecBase <NativeBeekonRnSpec>
4
8
 
5
9
  @end
package/ios/BeekonRn.mm CHANGED
@@ -1,6 +1,8 @@
1
1
  #import "BeekonRn.h"
2
- // Auto-generated bridging header from the Swift impl in this same target.
3
- #import "BeekonRn-Swift.h"
2
+ // Auto-generated bridging header from the Swift impl. With `use_frameworks!`
3
+ // in the host Podfile (required for Swift pods), CocoaPods generates this
4
+ // inside the BeekonRn framework, so the framework-style import is needed.
5
+ #import <BeekonRn/BeekonRn-Swift.h>
4
6
 
5
7
  @implementation BeekonRn {
6
8
  BeekonRnImpl *_impl;
@@ -11,38 +13,31 @@
11
13
  if (self) {
12
14
  __weak __typeof(self) weakSelf = self;
13
15
  _impl = [[BeekonRnImpl alloc]
14
- initWithOnState:^(NSDictionary *_Nonnull s) {
16
+ initOnState:^(NSDictionary *_Nonnull s) {
15
17
  [weakSelf emitOnState:s];
16
18
  }
17
- onPosition:^(NSDictionary *_Nonnull p) {
18
- [weakSelf emitOnPosition:p];
19
- }];
19
+ onLocation:^(NSDictionary *_Nonnull l) {
20
+ [weakSelf emitOnLocation:l];
21
+ }];
20
22
  }
21
23
  return self;
22
24
  }
23
25
 
24
- - (void)initialize:(RCTPromiseResolveBlock)resolve
25
- reject:(RCTPromiseRejectBlock)reject {
26
- [_impl initializeWithResolver:resolve rejecter:reject];
26
+ - (void)invalidate {
27
+ [_impl invalidate];
28
+ [super invalidate];
27
29
  }
28
30
 
29
31
  - (void)configure:(JS::NativeBeekonRn::WireConfig &)config
30
32
  resolve:(RCTPromiseResolveBlock)resolve
31
33
  reject:(RCTPromiseRejectBlock)reject {
32
34
  // Codegen passes the struct; round-trip through NSDictionary so the Swift
33
- // side can decode generically without an iOS-specific spec import.
34
- // (`config.toDictionary()` may also be available depending on RN version.)
35
+ // side can decode generically without an iOS-specific spec import. iOS
36
+ // ignores `androidNotification` passed through but unused.
35
37
  NSDictionary *dict = @{
36
- @"preset": config.preset() ?: @"balanced",
37
- @"distanceFilterMeters": config.distanceFilterMeters().has_value()
38
- ? @(config.distanceFilterMeters().value())
39
- : (id)[NSNull null],
40
- @"intervalMillis": config.intervalMillis().has_value()
41
- ? @(config.intervalMillis().value())
42
- : (id)[NSNull null],
43
- @"licenseKey": config.licenseKey() ?: (id)[NSNull null],
38
+ @"intervalSeconds": @(config.intervalSeconds()),
39
+ @"distanceMeters": @(config.distanceMeters()),
44
40
  };
45
- // Note: iOS doesn't use androidNotification — passed but ignored.
46
41
  [_impl configure:dict resolver:resolve rejecter:reject];
47
42
  }
48
43
 
@@ -56,11 +51,6 @@
56
51
  [_impl stopWithResolver:resolve rejecter:reject];
57
52
  }
58
53
 
59
- - (void)shutdown:(RCTPromiseResolveBlock)resolve
60
- reject:(RCTPromiseRejectBlock)reject {
61
- [_impl shutdownWithResolver:resolve rejecter:reject];
62
- }
63
-
64
54
  - (void)history:(double)fromMs
65
55
  toMs:(double)toMs
66
56
  resolve:(RCTPromiseResolveBlock)resolve