spotny-sdk 0.3.8 → 0.3.9
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.
Potentially problematic release.
This version of spotny-sdk might be problematic. Click here for more details.
- package/README.md +45 -132
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# spotny-sdk
|
|
2
2
|
|
|
3
|
-
A React Native SDK for
|
|
3
|
+
A React Native SDK for real-time proximity experiences. Detects nearby points of interest and fires location events on iOS and Android.
|
|
4
4
|
|
|
5
5
|
> Requires **React Native 0.73+** with the New Architecture (Turbo Modules) enabled.
|
|
6
6
|
|
|
@@ -24,11 +24,11 @@ Add the following keys to your `Info.plist`:
|
|
|
24
24
|
|
|
25
25
|
```xml
|
|
26
26
|
<key>NSLocationWhenInUseUsageDescription</key>
|
|
27
|
-
<string>We use your location to detect nearby
|
|
27
|
+
<string>We use your location to detect nearby points of interest.</string>
|
|
28
28
|
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
|
|
29
|
-
<string>We use your location in the background to detect nearby
|
|
29
|
+
<string>We use your location in the background to detect nearby points of interest.</string>
|
|
30
30
|
<key>NSBluetoothAlwaysUsageDescription</key>
|
|
31
|
-
<string>We use Bluetooth to
|
|
31
|
+
<string>We use Bluetooth to detect nearby points of interest.</string>
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
Enable **Background Modes** in Xcode → your app target → **Signing & Capabilities** → **+ Capability** → Background Modes:
|
|
@@ -36,7 +36,7 @@ Enable **Background Modes** in Xcode → your app target → **Signing & Capabil
|
|
|
36
36
|
- ✅ Location updates
|
|
37
37
|
- ✅ Uses Bluetooth LE accessories
|
|
38
38
|
|
|
39
|
-
> **
|
|
39
|
+
> **Note:** Background scanning requires the _Location updates_ background mode. The SDK works without it for foreground-only use.
|
|
40
40
|
|
|
41
41
|
### Android
|
|
42
42
|
|
|
@@ -60,32 +60,28 @@ import {
|
|
|
60
60
|
configure,
|
|
61
61
|
startScanner,
|
|
62
62
|
stopScanner,
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
addProximityListener,
|
|
64
|
+
addLocationEventListener,
|
|
65
65
|
} from 'spotny-sdk';
|
|
66
66
|
|
|
67
67
|
export default function App() {
|
|
68
68
|
useEffect(() => {
|
|
69
|
-
|
|
70
|
-
configure({ maxDetectionDistance: 10 });
|
|
71
|
-
|
|
72
|
-
// Start scanning with a unique device/user identifier
|
|
69
|
+
configure({ source: 'nike', maxDetectionDistance: 10 });
|
|
73
70
|
startScanner('device-uuid-here', /* userId */ null);
|
|
74
71
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
console.log('Beacons in range:', beacons);
|
|
72
|
+
const proxSub = addProximityListener((items) => {
|
|
73
|
+
console.log('Nearby:', items);
|
|
78
74
|
});
|
|
79
75
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
console.log(
|
|
76
|
+
const locationSub = addLocationEventListener(({ event, zone }) => {
|
|
77
|
+
if (event === 'enter') console.log('Entered zone', zone);
|
|
78
|
+
if (event === 'exit') console.log('Left zone', zone);
|
|
83
79
|
});
|
|
84
80
|
|
|
85
81
|
return () => {
|
|
86
82
|
stopScanner();
|
|
87
|
-
|
|
88
|
-
|
|
83
|
+
proxSub.remove();
|
|
84
|
+
locationSub.remove();
|
|
89
85
|
};
|
|
90
86
|
}, []);
|
|
91
87
|
|
|
@@ -97,18 +93,18 @@ export default function App() {
|
|
|
97
93
|
|
|
98
94
|
## API Reference
|
|
99
95
|
|
|
100
|
-
### Core
|
|
96
|
+
### Core
|
|
101
97
|
|
|
102
98
|
#### `startScanner(userUUID, userId?)`
|
|
103
99
|
|
|
104
|
-
Starts
|
|
100
|
+
Starts proximity scanning.
|
|
105
101
|
|
|
106
|
-
| Parameter | Type | Required | Description
|
|
107
|
-
| ---------- | ---------------- | -------- |
|
|
108
|
-
| `userUUID` | `string` | Yes | Unique identifier for this
|
|
109
|
-
| `userId` | `number \| null` | No | Authenticated user ID
|
|
102
|
+
| Parameter | Type | Required | Description |
|
|
103
|
+
| ---------- | ---------------- | -------- | ----------------------------------------- |
|
|
104
|
+
| `userUUID` | `string` | Yes | Unique identifier for this device/session |
|
|
105
|
+
| `userId` | `number \| null` | No | Authenticated user ID |
|
|
110
106
|
|
|
111
|
-
Returns `Promise<string
|
|
107
|
+
Returns `Promise<string>`.
|
|
112
108
|
|
|
113
109
|
```ts
|
|
114
110
|
await startScanner('550e8400-e29b-41d4-a716-446655440000', 42);
|
|
@@ -118,23 +114,15 @@ await startScanner('550e8400-e29b-41d4-a716-446655440000', 42);
|
|
|
118
114
|
|
|
119
115
|
#### `stopScanner()`
|
|
120
116
|
|
|
121
|
-
Stops scanning
|
|
117
|
+
Stops scanning and clears all state.
|
|
122
118
|
|
|
123
119
|
Returns `Promise<string>`.
|
|
124
120
|
|
|
125
|
-
```ts
|
|
126
|
-
await stopScanner();
|
|
127
|
-
```
|
|
128
|
-
|
|
129
121
|
---
|
|
130
122
|
|
|
131
123
|
#### `isScanning()`
|
|
132
124
|
|
|
133
|
-
Returns `Promise<boolean
|
|
134
|
-
|
|
135
|
-
```ts
|
|
136
|
-
const scanning = await isScanning();
|
|
137
|
-
```
|
|
125
|
+
Returns `Promise<boolean>`.
|
|
138
126
|
|
|
139
127
|
---
|
|
140
128
|
|
|
@@ -142,17 +130,15 @@ const scanning = await isScanning();
|
|
|
142
130
|
|
|
143
131
|
#### `configure(config)`
|
|
144
132
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
| Option | Type | Default | Description |
|
|
148
|
-
| ---------------------- | -------- | ------- | ------------------------------------------------------------------------------- |
|
|
149
|
-
| `maxDetectionDistance` | `number` | `8.0` | Maximum beacon detection radius (metres) |
|
|
150
|
-
| `source` | `string` | – | Identifier for your brand or app (e.g. `'nike'`). |
|
|
133
|
+
Call **before** `startScanner`.
|
|
151
134
|
|
|
152
|
-
|
|
135
|
+
| Option | Type | Default | Description |
|
|
136
|
+
| ---------------------- | -------- | ------- | -------------------------------------------- |
|
|
137
|
+
| `source` | `string` | – | Your brand or app identifier (e.g. `'nike'`) |
|
|
138
|
+
| `maxDetectionDistance` | `number` | `8.0` | Detection radius in metres |
|
|
153
139
|
|
|
154
140
|
```ts
|
|
155
|
-
await configure({
|
|
141
|
+
await configure({ source: 'nike', maxDetectionDistance: 10 });
|
|
156
142
|
```
|
|
157
143
|
|
|
158
144
|
---
|
|
@@ -161,139 +147,66 @@ await configure({ maxDetectionDistance: 12, source: 'nike' });
|
|
|
161
147
|
|
|
162
148
|
#### `requestNotificationPermissions()` _(iOS only)_
|
|
163
149
|
|
|
164
|
-
|
|
150
|
+
Requests local notification permissions.
|
|
165
151
|
|
|
166
152
|
Returns `Promise<string>`.
|
|
167
153
|
|
|
168
|
-
```ts
|
|
169
|
-
await requestNotificationPermissions();
|
|
170
|
-
```
|
|
171
|
-
|
|
172
154
|
---
|
|
173
155
|
|
|
174
156
|
### Event Listeners
|
|
175
157
|
|
|
176
158
|
#### `addBeaconsRangedListener(callback)`
|
|
177
159
|
|
|
178
|
-
Fires
|
|
160
|
+
Fires when nearby items are detected (approximately every second).
|
|
179
161
|
|
|
180
162
|
```ts
|
|
181
|
-
const
|
|
182
|
-
beacons.forEach((
|
|
183
|
-
console.log(`${
|
|
163
|
+
const sub = addBeaconsRangedListener(({ beacons }) => {
|
|
164
|
+
beacons.forEach((item) => {
|
|
165
|
+
console.log(`${item.distance.toFixed(1)} m — ${item.proximity}`);
|
|
184
166
|
});
|
|
185
167
|
});
|
|
186
168
|
|
|
187
|
-
//
|
|
188
|
-
subscription.remove();
|
|
169
|
+
sub.remove(); // when done
|
|
189
170
|
```
|
|
190
171
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
| Field | Type | Description |
|
|
194
|
-
| --------- | -------------- | ------------------------ |
|
|
195
|
-
| `beacons` | `BeaconData[]` | Array of visible beacons |
|
|
196
|
-
| `region` | `string` | Beacon region identifier |
|
|
197
|
-
|
|
198
|
-
**`BeaconData`:**
|
|
172
|
+
Each item contains:
|
|
199
173
|
|
|
200
174
|
| Field | Type | Description |
|
|
201
175
|
| ----------- | -------- | --------------------------------------------------- |
|
|
202
|
-
| `uuid` | `string` | Proximity UUID |
|
|
203
|
-
| `major` | `number` | Major value |
|
|
204
|
-
| `minor` | `number` | Minor value |
|
|
205
176
|
| `distance` | `number` | Estimated distance in metres |
|
|
206
|
-
| `rssi` | `number` | Signal strength (dBm) |
|
|
207
177
|
| `proximity` | `string` | `'immediate'` \| `'near'` \| `'far'` \| `'unknown'` |
|
|
208
178
|
|
|
209
179
|
---
|
|
210
180
|
|
|
211
181
|
#### `addBeaconRegionListener(callback)`
|
|
212
182
|
|
|
213
|
-
Fires
|
|
183
|
+
Fires when the user enters or exits a zone. Works in foreground, background, and terminated state (iOS).
|
|
214
184
|
|
|
215
185
|
```ts
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
if (event === 'exit') console.log('Exited', region);
|
|
186
|
+
const sub = addBeaconRegionListener(({ event, region, state }) => {
|
|
187
|
+
console.log(event, region); // 'enter' | 'exit' | 'determined'
|
|
219
188
|
});
|
|
220
189
|
|
|
221
|
-
//
|
|
222
|
-
subscription.remove();
|
|
190
|
+
sub.remove(); // when done
|
|
223
191
|
```
|
|
224
192
|
|
|
225
|
-
**Callback payload — `BeaconRegionEvent`:**
|
|
226
|
-
|
|
227
193
|
| Field | Type | Description |
|
|
228
194
|
| -------- | -------- | ---------------------------------------------------------- |
|
|
229
|
-
| `region` | `string` | Region identifier |
|
|
230
195
|
| `event` | `string` | `'enter'` \| `'exit'` \| `'determined'` |
|
|
196
|
+
| `region` | `string` | Zone identifier |
|
|
231
197
|
| `state` | `string` | `'inside'` \| `'outside'` \| `'unknown'` (determined only) |
|
|
232
198
|
|
|
233
199
|
---
|
|
234
200
|
|
|
235
|
-
### Debounce Helpers
|
|
236
|
-
|
|
237
|
-
These let you tune how often repeated proximity events are emitted for the same beacon.
|
|
238
|
-
|
|
239
|
-
#### `setDebounceInterval(seconds)`
|
|
240
|
-
|
|
241
|
-
Sets the minimum gap (in seconds) between proximity events for the same beacon.
|
|
242
|
-
|
|
243
|
-
```ts
|
|
244
|
-
await setDebounceInterval(30); // fire at most once per 30 s per beacon
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
#### `clearDebounceCache()`
|
|
248
|
-
|
|
249
|
-
Resets cooldown state for all beacons, allowing them to fire again immediately.
|
|
250
|
-
|
|
251
|
-
```ts
|
|
252
|
-
await clearDebounceCache();
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
#### `getDebounceStatus()`
|
|
256
|
-
|
|
257
|
-
Returns the current cooldown state for all tracked beacons.
|
|
258
|
-
|
|
259
|
-
```ts
|
|
260
|
-
const status = await getDebounceStatus();
|
|
261
|
-
console.log(status);
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
---
|
|
265
|
-
|
|
266
201
|
### Debug Helpers
|
|
267
202
|
|
|
268
203
|
#### `getDebugLogs()`
|
|
269
204
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
```ts
|
|
273
|
-
const logs = await getDebugLogs();
|
|
274
|
-
console.log(logs);
|
|
275
|
-
```
|
|
205
|
+
Returns on-device debug logs as a string.
|
|
276
206
|
|
|
277
207
|
#### `clearDebugLogs()`
|
|
278
208
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
```ts
|
|
282
|
-
await clearDebugLogs();
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
---
|
|
286
|
-
|
|
287
|
-
## TypeScript Types
|
|
288
|
-
|
|
289
|
-
```ts
|
|
290
|
-
import type {
|
|
291
|
-
BeaconData,
|
|
292
|
-
BeaconRangedEvent,
|
|
293
|
-
BeaconRegionEvent,
|
|
294
|
-
SpotnySdkConfig,
|
|
295
|
-
} from 'spotny-sdk';
|
|
296
|
-
```
|
|
209
|
+
Clears on-device debug logs.
|
|
297
210
|
|
|
298
211
|
---
|
|
299
212
|
|
|
@@ -301,7 +214,7 @@ import type {
|
|
|
301
214
|
|
|
302
215
|
| Feature | iOS | Android |
|
|
303
216
|
| ------------------------ | --- | ------- |
|
|
304
|
-
|
|
|
217
|
+
| Zone monitoring | ✅ | ✅ |
|
|
305
218
|
| Background scanning | ✅ | ✅ |
|
|
306
219
|
| Terminated-state wakeup | ✅ | ✅ |
|
|
307
220
|
| Notification permissions | ✅ | – |
|