@wayq/beekon-rn 0.0.1

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 (69) hide show
  1. package/BeekonRn.podspec +37 -0
  2. package/LICENSE.txt +14 -0
  3. package/README.md +122 -0
  4. package/android/build.gradle +81 -0
  5. package/android/src/main/AndroidManifest.xml +2 -0
  6. package/android/src/main/java/com/wayq/beekonrn/BeekonRnModule.kt +233 -0
  7. package/android/src/main/java/com/wayq/beekonrn/BeekonRnPackage.kt +31 -0
  8. package/ios/BeekonRn.h +5 -0
  9. package/ios/BeekonRn.mm +80 -0
  10. package/ios/BeekonRn.swift +211 -0
  11. package/ios/Frameworks/BeekonKit.xcframework/Info.plist +44 -0
  12. package/ios/Frameworks/BeekonKit.xcframework/LICENSE.txt +14 -0
  13. package/ios/Frameworks/BeekonKit.xcframework/_CodeSignature/CodeDirectory +0 -0
  14. package/ios/Frameworks/BeekonKit.xcframework/_CodeSignature/CodeRequirements +0 -0
  15. package/ios/Frameworks/BeekonKit.xcframework/_CodeSignature/CodeRequirements-1 +0 -0
  16. package/ios/Frameworks/BeekonKit.xcframework/_CodeSignature/CodeResources +233 -0
  17. package/ios/Frameworks/BeekonKit.xcframework/_CodeSignature/CodeSignature +0 -0
  18. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/BeekonKit +0 -0
  19. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/Info.plist +0 -0
  20. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/PrivacyInfo.xcprivacy +77 -0
  21. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64/BeekonKit.framework/_CodeSignature/CodeResources +113 -0
  22. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/BeekonKit +0 -0
  23. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/Info.plist +0 -0
  24. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/PrivacyInfo.xcprivacy +77 -0
  25. package/ios/Frameworks/BeekonKit.xcframework/ios-arm64_x86_64-simulator/BeekonKit.framework/_CodeSignature/CodeResources +113 -0
  26. package/lib/module/NativeBeekonRn.js +16 -0
  27. package/lib/module/NativeBeekonRn.js.map +1 -0
  28. package/lib/module/beekon.js +107 -0
  29. package/lib/module/beekon.js.map +1 -0
  30. package/lib/module/index.js +4 -0
  31. package/lib/module/index.js.map +1 -0
  32. package/lib/module/internal/mappers.js +58 -0
  33. package/lib/module/internal/mappers.js.map +1 -0
  34. package/lib/module/package.json +1 -0
  35. package/lib/module/types/config.js +4 -0
  36. package/lib/module/types/config.js.map +1 -0
  37. package/lib/module/types/position.js +2 -0
  38. package/lib/module/types/position.js.map +1 -0
  39. package/lib/module/types/preset.js +2 -0
  40. package/lib/module/types/preset.js.map +1 -0
  41. package/lib/module/types/state.js +2 -0
  42. package/lib/module/types/state.js.map +1 -0
  43. package/lib/typescript/package.json +1 -0
  44. package/lib/typescript/src/NativeBeekonRn.d.ts +58 -0
  45. package/lib/typescript/src/NativeBeekonRn.d.ts.map +1 -0
  46. package/lib/typescript/src/beekon.d.ts +80 -0
  47. package/lib/typescript/src/beekon.d.ts.map +1 -0
  48. package/lib/typescript/src/index.d.ts +6 -0
  49. package/lib/typescript/src/index.d.ts.map +1 -0
  50. package/lib/typescript/src/internal/mappers.d.ts +8 -0
  51. package/lib/typescript/src/internal/mappers.d.ts.map +1 -0
  52. package/lib/typescript/src/types/config.d.ts +41 -0
  53. package/lib/typescript/src/types/config.d.ts.map +1 -0
  54. package/lib/typescript/src/types/position.d.ts +24 -0
  55. package/lib/typescript/src/types/position.d.ts.map +1 -0
  56. package/lib/typescript/src/types/preset.d.ts +12 -0
  57. package/lib/typescript/src/types/preset.d.ts.map +1 -0
  58. package/lib/typescript/src/types/state.d.ts +22 -0
  59. package/lib/typescript/src/types/state.d.ts.map +1 -0
  60. package/package.json +137 -0
  61. package/scripts/fetch-beekonkit.sh +58 -0
  62. package/src/NativeBeekonRn.ts +64 -0
  63. package/src/beekon.ts +110 -0
  64. package/src/index.tsx +5 -0
  65. package/src/internal/mappers.ts +50 -0
  66. package/src/types/config.ts +42 -0
  67. package/src/types/position.ts +23 -0
  68. package/src/types/preset.ts +11 -0
  69. package/src/types/state.ts +16 -0
@@ -0,0 +1,211 @@
1
+ import Foundation
2
+ import BeekonKit
3
+
4
+ /// Swift impl of the Beekon RN TurboModule. Bridges the actor-based native
5
+ /// SDK (`BeekonKit.Beekon.shared`) to the ObjC TurboModule conformance in
6
+ /// `BeekonRn.mm`. All public-facing methods take ObjC-compatible callbacks
7
+ /// (resolver/rejecter) and dictionaries so they can be invoked from `.mm`.
8
+ ///
9
+ /// Event delivery: `BeekonRn.mm` constructs this with two closures that call
10
+ /// the codegen-generated `emitOnState:` / `emitOnPosition:` ObjC methods on
11
+ /// the spec; the closures are invoked from the per-stream `Task`s started
12
+ /// during `initialize`.
13
+ @objc public final class BeekonRnImpl: NSObject {
14
+
15
+ private let onStateCb: (NSDictionary) -> Void
16
+ private let onPositionCb: (NSDictionary) -> Void
17
+
18
+ private var stateTask: Task<Void, Never>?
19
+ private var positionsTask: Task<Void, Never>?
20
+
21
+ @objc public init(
22
+ onState: @escaping (NSDictionary) -> Void,
23
+ onPosition: @escaping (NSDictionary) -> Void
24
+ ) {
25
+ self.onStateCb = onState
26
+ self.onPositionCb = onPosition
27
+ super.init()
28
+ }
29
+
30
+ // MARK: - Lifecycle
31
+
32
+ @objc public func initializeWithResolver(
33
+ _ resolve: @escaping (Any?) -> Void,
34
+ rejecter reject: @escaping (String?, String?, Error?) -> Void
35
+ ) {
36
+ Task { [weak self] in
37
+ guard let self = self else { return }
38
+ do {
39
+ try await Beekon.shared.initialize()
40
+ // Idempotent: cancel any prior collectors before starting new ones.
41
+ self.stateTask?.cancel()
42
+ self.positionsTask?.cancel()
43
+ self.stateTask = Task { [weak self] in
44
+ guard let self = self else { return }
45
+ for await state in await Beekon.shared.state {
46
+ self.onStateCb(self.stateToWire(state))
47
+ }
48
+ }
49
+ self.positionsTask = Task { [weak self] in
50
+ guard let self = self else { return }
51
+ for await pos in await Beekon.shared.positions {
52
+ self.onPositionCb(self.positionToWire(pos))
53
+ }
54
+ }
55
+ resolve(nil)
56
+ } catch {
57
+ reject(self.errorCode(error), error.localizedDescription, error)
58
+ }
59
+ }
60
+ }
61
+
62
+ @objc public func configure(
63
+ _ config: NSDictionary,
64
+ resolver resolve: @escaping RCTPromiseResolveBlock,
65
+ rejecter reject: @escaping RCTPromiseRejectBlock
66
+ ) {
67
+ Task { [weak self] in
68
+ guard let self = self else { return }
69
+ do {
70
+ let cfg = try self.wireToConfig(config)
71
+ await Beekon.shared.configure(cfg)
72
+ resolve(nil)
73
+ } catch {
74
+ reject(self.errorCode(error), error.localizedDescription, error)
75
+ }
76
+ }
77
+ }
78
+
79
+ @objc public func startWithResolver(
80
+ _ resolve: @escaping (Any?) -> Void,
81
+ rejecter reject: @escaping (String?, String?, Error?) -> Void
82
+ ) {
83
+ Task { [weak self] in
84
+ guard let self = self else { return }
85
+ do {
86
+ try await Beekon.shared.start()
87
+ resolve(nil)
88
+ } catch {
89
+ reject(self.errorCode(error), error.localizedDescription, error)
90
+ }
91
+ }
92
+ }
93
+
94
+ @objc public func stopWithResolver(
95
+ _ resolve: @escaping (Any?) -> Void,
96
+ rejecter reject: @escaping (String?, String?, Error?) -> Void
97
+ ) {
98
+ Task { [weak self] in
99
+ guard let self = self else { return }
100
+ await Beekon.shared.stop()
101
+ resolve(nil)
102
+ }
103
+ }
104
+
105
+ @objc public func shutdownWithResolver(
106
+ _ resolve: @escaping (Any?) -> Void,
107
+ rejecter reject: @escaping (String?, String?, Error?) -> Void
108
+ ) {
109
+ Task { [weak self] in
110
+ guard let self = self else { return }
111
+ self.stateTask?.cancel()
112
+ self.positionsTask?.cancel()
113
+ await Beekon.shared.shutdown()
114
+ resolve(nil)
115
+ }
116
+ }
117
+
118
+ @objc public func historyFromMs(
119
+ _ fromMs: Double,
120
+ toMs: Double,
121
+ resolver resolve: @escaping RCTPromiseResolveBlock,
122
+ rejecter reject: @escaping RCTPromiseRejectBlock
123
+ ) {
124
+ Task { [weak self] in
125
+ guard let self = self else { return }
126
+ do {
127
+ let from = Date(timeIntervalSince1970: fromMs / 1000.0)
128
+ let to = Date(timeIntervalSince1970: toMs / 1000.0)
129
+ let positions = try await Beekon.shared.history(from: from, to: to)
130
+ let arr = positions.map { self.positionToWire($0) }
131
+ resolve(arr)
132
+ } catch {
133
+ reject(self.errorCode(error), error.localizedDescription, error)
134
+ }
135
+ }
136
+ }
137
+
138
+ // MARK: - Mappers
139
+
140
+ private func wireToConfig(_ d: NSDictionary) throws -> BeekonConfig {
141
+ let presetStr = (d["preset"] as? String) ?? "balanced"
142
+ let preset: Preset
143
+ switch presetStr {
144
+ case "saver": preset = .saver
145
+ case "precision": preset = .precision
146
+ default: preset = .balanced
147
+ }
148
+
149
+ let distanceFilterMeters = d["distanceFilterMeters"] as? Double
150
+ // JS sends millis; iOS BeekonConfig wants seconds. Normalize here.
151
+ let intervalSeconds: Double?
152
+ if let ms = d["intervalMillis"] as? Double {
153
+ intervalSeconds = ms / 1000.0
154
+ } else {
155
+ intervalSeconds = nil
156
+ }
157
+ let licenseKey = d["licenseKey"] as? String
158
+
159
+ return BeekonConfig(
160
+ preset: preset,
161
+ distanceFilterMeters: distanceFilterMeters,
162
+ intervalSeconds: intervalSeconds,
163
+ licenseKey: licenseKey
164
+ )
165
+ }
166
+
167
+ private func positionToWire(_ p: Position) -> NSDictionary {
168
+ return [
169
+ "lat": p.lat,
170
+ "lng": p.lng,
171
+ "accuracy": p.accuracy,
172
+ "speed": p.speed,
173
+ "bearing": p.bearing,
174
+ "altitude": p.altitude,
175
+ "timestampMs": p.timestamp.timeIntervalSince1970 * 1000.0,
176
+ ]
177
+ }
178
+
179
+ private func stateToWire(_ s: BeekonState) -> NSDictionary {
180
+ switch s {
181
+ case .idle: return ["type": "idle"]
182
+ case .starting: return ["type": "starting"]
183
+ case .tracking: return ["type": "tracking"]
184
+ case .stopped: return ["type": "stopped"]
185
+ case .paused(let reason):
186
+ let r: String
187
+ switch reason {
188
+ case .permissionRevoked: r = "permissionRevoked"
189
+ case .locationDisabled: r = "locationDisabled"
190
+ case .unknown: r = "unknown"
191
+ }
192
+ return ["type": "paused", "pauseReason": r]
193
+ }
194
+ }
195
+
196
+ /// Maps native `BeekonError` cases to stable string codes shared with
197
+ /// Android. JS-side error handling can switch on these without per-platform
198
+ /// branches.
199
+ private func errorCode(_ e: Error) -> String {
200
+ if let be = e as? BeekonError {
201
+ switch be {
202
+ case .permissionDenied: return "PERMISSION_DENIED"
203
+ case .locationServicesDisabled: return "LOCATION_SERVICES_DISABLED"
204
+ case .notConfigured: return "NOT_CONFIGURED"
205
+ case .notInitialised: return "NOT_INITIALISED"
206
+ case .internalError: return "INTERNAL_ERROR"
207
+ }
208
+ }
209
+ return "INTERNAL_ERROR"
210
+ }
211
+ }
@@ -0,0 +1,44 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>AvailableLibraries</key>
6
+ <array>
7
+ <dict>
8
+ <key>BinaryPath</key>
9
+ <string>BeekonKit.framework/BeekonKit</string>
10
+ <key>LibraryIdentifier</key>
11
+ <string>ios-arm64_x86_64-simulator</string>
12
+ <key>LibraryPath</key>
13
+ <string>BeekonKit.framework</string>
14
+ <key>SupportedArchitectures</key>
15
+ <array>
16
+ <string>arm64</string>
17
+ <string>x86_64</string>
18
+ </array>
19
+ <key>SupportedPlatform</key>
20
+ <string>ios</string>
21
+ <key>SupportedPlatformVariant</key>
22
+ <string>simulator</string>
23
+ </dict>
24
+ <dict>
25
+ <key>BinaryPath</key>
26
+ <string>BeekonKit.framework/BeekonKit</string>
27
+ <key>LibraryIdentifier</key>
28
+ <string>ios-arm64</string>
29
+ <key>LibraryPath</key>
30
+ <string>BeekonKit.framework</string>
31
+ <key>SupportedArchitectures</key>
32
+ <array>
33
+ <string>arm64</string>
34
+ </array>
35
+ <key>SupportedPlatform</key>
36
+ <string>ios</string>
37
+ </dict>
38
+ </array>
39
+ <key>CFBundlePackageType</key>
40
+ <string>XFWK</string>
41
+ <key>XCFrameworkFormatVersion</key>
42
+ <string>1.0</string>
43
+ </dict>
44
+ </plist>
@@ -0,0 +1,14 @@
1
+ Beekon SDK
2
+ Copyright (c) 2026 wayqteam. All rights reserved.
3
+
4
+ This software is licensed for evaluation use only. No production deployment,
5
+ redistribution, sublicensing, or commercial use is permitted without a separate
6
+ written agreement with wayqteam.
7
+
8
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
10
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
11
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING
12
+ FROM USE OF THE SOFTWARE.
13
+
14
+ For licensing inquiries: contact wayqteam.
@@ -0,0 +1,233 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>files</key>
6
+ <dict>
7
+ <key>LICENSE.txt</key>
8
+ <data>
9
+ Cd50llceWtwBPWNSIAJRdTfQQiE=
10
+ </data>
11
+ <key>ios-arm64/BeekonKit.framework/BeekonKit</key>
12
+ <data>
13
+ SyrIBjwS5o/8csiCfKIXmBtvzio=
14
+ </data>
15
+ <key>ios-arm64/BeekonKit.framework/Info.plist</key>
16
+ <data>
17
+ 3d/2OPEwv55L8dW+0woT9NRCNi0=
18
+ </data>
19
+ <key>ios-arm64/BeekonKit.framework/PrivacyInfo.xcprivacy</key>
20
+ <data>
21
+ +Hzj9e+o3dYoDboCDA7ofM2a0kc=
22
+ </data>
23
+ <key>ios-arm64/BeekonKit.framework/_CodeSignature/CodeResources</key>
24
+ <data>
25
+ iZuijJG0soEo1jfi0V3NeqZXX4s=
26
+ </data>
27
+ <key>ios-arm64_x86_64-simulator/BeekonKit.framework/BeekonKit</key>
28
+ <data>
29
+ cEmeEm6qJLQueaJja0nxBKt+nEA=
30
+ </data>
31
+ <key>ios-arm64_x86_64-simulator/BeekonKit.framework/Info.plist</key>
32
+ <data>
33
+ w9rsPHfS6nhyFAFD48jpWHGzYuc=
34
+ </data>
35
+ <key>ios-arm64_x86_64-simulator/BeekonKit.framework/PrivacyInfo.xcprivacy</key>
36
+ <data>
37
+ +Hzj9e+o3dYoDboCDA7ofM2a0kc=
38
+ </data>
39
+ <key>ios-arm64_x86_64-simulator/BeekonKit.framework/_CodeSignature/CodeResources</key>
40
+ <data>
41
+ hbmbyZ85ag/7tawlrdWmUyumzVo=
42
+ </data>
43
+ </dict>
44
+ <key>files2</key>
45
+ <dict>
46
+ <key>LICENSE.txt</key>
47
+ <dict>
48
+ <key>hash</key>
49
+ <data>
50
+ Cd50llceWtwBPWNSIAJRdTfQQiE=
51
+ </data>
52
+ <key>hash2</key>
53
+ <data>
54
+ PDylgJZfZxoKTHUmgv6aK1hRYtMtH4titPlIb7e5iRY=
55
+ </data>
56
+ </dict>
57
+ <key>ios-arm64/BeekonKit.framework/BeekonKit</key>
58
+ <dict>
59
+ <key>hash</key>
60
+ <data>
61
+ SyrIBjwS5o/8csiCfKIXmBtvzio=
62
+ </data>
63
+ <key>hash2</key>
64
+ <data>
65
+ sJNDsLwayhdCOxwHz2nvh5hWAy7aH+1xYTklkXYLTVo=
66
+ </data>
67
+ </dict>
68
+ <key>ios-arm64/BeekonKit.framework/Info.plist</key>
69
+ <dict>
70
+ <key>hash</key>
71
+ <data>
72
+ 3d/2OPEwv55L8dW+0woT9NRCNi0=
73
+ </data>
74
+ <key>hash2</key>
75
+ <data>
76
+ pwRHyHj1JmPCiUn+GAAwVdCWQOj+rrrs7WDjyfqTwcE=
77
+ </data>
78
+ </dict>
79
+ <key>ios-arm64/BeekonKit.framework/PrivacyInfo.xcprivacy</key>
80
+ <dict>
81
+ <key>hash</key>
82
+ <data>
83
+ +Hzj9e+o3dYoDboCDA7ofM2a0kc=
84
+ </data>
85
+ <key>hash2</key>
86
+ <data>
87
+ E3plr2RiT1CPWdLg5VfDUw1k7yShykpszuDqfKG4YYw=
88
+ </data>
89
+ </dict>
90
+ <key>ios-arm64/BeekonKit.framework/_CodeSignature/CodeResources</key>
91
+ <dict>
92
+ <key>hash</key>
93
+ <data>
94
+ iZuijJG0soEo1jfi0V3NeqZXX4s=
95
+ </data>
96
+ <key>hash2</key>
97
+ <data>
98
+ qgFb+LKTIRzW2w+dr7F9VFD6m1FpP0HSjHBtgwKpkxk=
99
+ </data>
100
+ </dict>
101
+ <key>ios-arm64_x86_64-simulator/BeekonKit.framework/BeekonKit</key>
102
+ <dict>
103
+ <key>hash</key>
104
+ <data>
105
+ cEmeEm6qJLQueaJja0nxBKt+nEA=
106
+ </data>
107
+ <key>hash2</key>
108
+ <data>
109
+ 1OteRVaQF1w/938f/tCgu7XydD6pJkclY8MQ8rUpc4c=
110
+ </data>
111
+ </dict>
112
+ <key>ios-arm64_x86_64-simulator/BeekonKit.framework/Info.plist</key>
113
+ <dict>
114
+ <key>hash</key>
115
+ <data>
116
+ w9rsPHfS6nhyFAFD48jpWHGzYuc=
117
+ </data>
118
+ <key>hash2</key>
119
+ <data>
120
+ Yr1G0VwEkAQ7fULqXaAcgXxuiXyV2ANn7hepvYQTcDo=
121
+ </data>
122
+ </dict>
123
+ <key>ios-arm64_x86_64-simulator/BeekonKit.framework/PrivacyInfo.xcprivacy</key>
124
+ <dict>
125
+ <key>hash</key>
126
+ <data>
127
+ +Hzj9e+o3dYoDboCDA7ofM2a0kc=
128
+ </data>
129
+ <key>hash2</key>
130
+ <data>
131
+ E3plr2RiT1CPWdLg5VfDUw1k7yShykpszuDqfKG4YYw=
132
+ </data>
133
+ </dict>
134
+ <key>ios-arm64_x86_64-simulator/BeekonKit.framework/_CodeSignature/CodeResources</key>
135
+ <dict>
136
+ <key>hash</key>
137
+ <data>
138
+ hbmbyZ85ag/7tawlrdWmUyumzVo=
139
+ </data>
140
+ <key>hash2</key>
141
+ <data>
142
+ wi0JVImM9cRW0rzNqoJGY96gS/irH4VrWsZvyoVDhZE=
143
+ </data>
144
+ </dict>
145
+ </dict>
146
+ <key>rules</key>
147
+ <dict>
148
+ <key>^.*</key>
149
+ <true/>
150
+ <key>^.*\.lproj/</key>
151
+ <dict>
152
+ <key>optional</key>
153
+ <true/>
154
+ <key>weight</key>
155
+ <real>1000</real>
156
+ </dict>
157
+ <key>^.*\.lproj/locversion.plist$</key>
158
+ <dict>
159
+ <key>omit</key>
160
+ <true/>
161
+ <key>weight</key>
162
+ <real>1100</real>
163
+ </dict>
164
+ <key>^Base\.lproj/</key>
165
+ <dict>
166
+ <key>weight</key>
167
+ <real>1010</real>
168
+ </dict>
169
+ <key>^version.plist$</key>
170
+ <true/>
171
+ </dict>
172
+ <key>rules2</key>
173
+ <dict>
174
+ <key>.*\.dSYM($|/)</key>
175
+ <dict>
176
+ <key>weight</key>
177
+ <real>11</real>
178
+ </dict>
179
+ <key>^(.*/)?\.DS_Store$</key>
180
+ <dict>
181
+ <key>omit</key>
182
+ <true/>
183
+ <key>weight</key>
184
+ <real>2000</real>
185
+ </dict>
186
+ <key>^.*</key>
187
+ <true/>
188
+ <key>^.*\.lproj/</key>
189
+ <dict>
190
+ <key>optional</key>
191
+ <true/>
192
+ <key>weight</key>
193
+ <real>1000</real>
194
+ </dict>
195
+ <key>^.*\.lproj/locversion.plist$</key>
196
+ <dict>
197
+ <key>omit</key>
198
+ <true/>
199
+ <key>weight</key>
200
+ <real>1100</real>
201
+ </dict>
202
+ <key>^Base\.lproj/</key>
203
+ <dict>
204
+ <key>weight</key>
205
+ <real>1010</real>
206
+ </dict>
207
+ <key>^Info\.plist$</key>
208
+ <dict>
209
+ <key>omit</key>
210
+ <true/>
211
+ <key>weight</key>
212
+ <real>20</real>
213
+ </dict>
214
+ <key>^PkgInfo$</key>
215
+ <dict>
216
+ <key>omit</key>
217
+ <true/>
218
+ <key>weight</key>
219
+ <real>20</real>
220
+ </dict>
221
+ <key>^embedded\.provisionprofile$</key>
222
+ <dict>
223
+ <key>weight</key>
224
+ <real>20</real>
225
+ </dict>
226
+ <key>^version\.plist$</key>
227
+ <dict>
228
+ <key>weight</key>
229
+ <real>20</real>
230
+ </dict>
231
+ </dict>
232
+ </dict>
233
+ </plist>
@@ -0,0 +1,77 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <!--
4
+ Beekon iOS SDK Privacy Manifest
5
+
6
+ Source of truth: this file. Included two ways:
7
+ 1. SwiftPM resource via Package.swift `.copy("PrivacyInfo.xcprivacy")`.
8
+ 2. Copied to each BeekonKit.framework/ root by scripts/build-xcframework.sh
9
+ so binary consumers of the xcframework find it at the Apple-required
10
+ location.
11
+
12
+ Required by Apple for SDKs distributed via SwiftPM since mid-2024. Validated
13
+ at App Store submission time when consumers archive an app embedding Beekon.
14
+
15
+ See https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
16
+ -->
17
+ <plist version="1.0">
18
+ <dict>
19
+ <!-- We do not track users across apps or websites. -->
20
+ <key>NSPrivacyTracking</key>
21
+ <false/>
22
+ <key>NSPrivacyTrackingDomains</key>
23
+ <array/>
24
+
25
+ <!--
26
+ Collected data. Beekon collects precise location for the host app's own
27
+ functionality (live tracking + history). Data is stored locally in the
28
+ host app's container (GRDB SQLite) and is not linked to user identity
29
+ from the SDK's perspective. The host app may link it to a user; that's
30
+ the host's call to declare in its own manifest.
31
+ -->
32
+ <key>NSPrivacyCollectedDataTypes</key>
33
+ <array>
34
+ <dict>
35
+ <key>NSPrivacyCollectedDataType</key>
36
+ <string>NSPrivacyCollectedDataTypePreciseLocation</string>
37
+ <key>NSPrivacyCollectedDataTypeLinked</key>
38
+ <false/>
39
+ <key>NSPrivacyCollectedDataTypeTracking</key>
40
+ <false/>
41
+ <key>NSPrivacyCollectedDataTypePurposes</key>
42
+ <array>
43
+ <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
44
+ </array>
45
+ </dict>
46
+ </array>
47
+
48
+ <!--
49
+ Required-Reason APIs we use:
50
+ - UserDefaults (CA92.1): StateHolder/TrackingPersistence stores the
51
+ last-known tracking config in the com.wayq.beekon UserDefaults suite
52
+ so SLC-driven relaunches can auto-restore tracking.
53
+ - File timestamp (3B52.1): GRDB queries timestamps on its own SQLite
54
+ database file inside the host app's container.
55
+ Reason codes per https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api
56
+ -->
57
+ <key>NSPrivacyAccessedAPITypes</key>
58
+ <array>
59
+ <dict>
60
+ <key>NSPrivacyAccessedAPIType</key>
61
+ <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
62
+ <key>NSPrivacyAccessedAPITypeReasons</key>
63
+ <array>
64
+ <string>CA92.1</string>
65
+ </array>
66
+ </dict>
67
+ <dict>
68
+ <key>NSPrivacyAccessedAPIType</key>
69
+ <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
70
+ <key>NSPrivacyAccessedAPITypeReasons</key>
71
+ <array>
72
+ <string>3B52.1</string>
73
+ </array>
74
+ </dict>
75
+ </array>
76
+ </dict>
77
+ </plist>