expo-beacon 0.5.3 → 0.5.4

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.
@@ -251,10 +251,12 @@ public class ExpoBeaconModule: Module {
251
251
 
252
252
  var eddystones = self.loadPairedEddystonesRaw()
253
253
  eddystones.removeAll { ($0["identifier"] as? String) == identifier }
254
+ // Normalize hex to lowercase — parseEddystoneFrame produces lowercase,
255
+ // so stored values must match for monitoring comparisons.
254
256
  eddystones.append([
255
257
  "identifier": identifier,
256
- "namespace": namespace,
257
- "instance": instance
258
+ "namespace": namespace.lowercased(),
259
+ "instance": instance.lowercased()
258
260
  ])
259
261
  self.defaults.set(eddystones, forKey: PAIRED_EDDYSTONES_KEY)
260
262
  self.cachedPairedEddystones = nil
@@ -662,27 +664,14 @@ public class ExpoBeaconModule: Module {
662
664
  guard let identifier = paired["identifier"] as? String,
663
665
  let pns = paired["namespace"] as? String,
664
666
  let pinst = paired["instance"] as? String,
665
- pns == ns && pinst == inst else { continue }
667
+ pns.lowercased() == ns && pinst.lowercased() == inst else { continue }
666
668
 
667
669
  eddystoneLatestSeen[identifier] = Date()
668
670
  eddystoneMissCounters[identifier] = 0
669
671
 
670
- // Throttle distance events
671
- let now = Date()
672
- if let lastEmit = eddystoneLastDistanceEmit[identifier],
673
- now.timeIntervalSince(lastEmit) < DISTANCE_EVENT_THROTTLE_INTERVAL {
674
- break
675
- }
676
- eddystoneLastDistanceEmit[identifier] = now
677
-
678
- sendEvent("onEddystoneDistance", [
679
- "identifier": identifier,
680
- "namespace": ns,
681
- "instance": inst,
682
- "distance": distance
683
- ])
684
-
685
- // Distance-driven enter/exit with hysteresis
672
+ // Distance-driven enter/exit with hysteresis — evaluated on every
673
+ // BLE callback (not throttled) so the hysteresis counters advance
674
+ // reliably regardless of advertisement rate.
686
675
  let maxDist = self.defaults.object(forKey: MAX_DISTANCE_KEY) as? Double
687
676
  let exitDist = self.defaults.object(forKey: EXIT_DISTANCE_KEY) as? Double
688
677
  let action = evaluateDistanceHysteresis(
@@ -716,6 +705,22 @@ public class ExpoBeaconModule: Module {
716
705
  case .none:
717
706
  break
718
707
  }
708
+
709
+ // Throttle distance events — enter/exit above is evaluated on every
710
+ // callback, but distance events are rate-limited to avoid flooding JS.
711
+ let now = Date()
712
+ if let lastEmit = eddystoneLastDistanceEmit[identifier],
713
+ now.timeIntervalSince(lastEmit) < DISTANCE_EVENT_THROTTLE_INTERVAL {
714
+ break
715
+ }
716
+ eddystoneLastDistanceEmit[identifier] = now
717
+
718
+ sendEvent("onEddystoneDistance", [
719
+ "identifier": identifier,
720
+ "namespace": ns,
721
+ "instance": inst,
722
+ "distance": distance
723
+ ])
719
724
  break
720
725
  }
721
726
  }
@@ -1213,9 +1218,12 @@ private class BluetoothDelegate: NSObject, CBCentralManagerDelegate {
1213
1218
  case .poweredOn:
1214
1219
  module?.ensureBleScanRunning()
1215
1220
  case .unauthorized:
1221
+ print("[ExpoBeacon] Bluetooth authorization denied — Eddystone scanning/monitoring unavailable. " +
1222
+ "Ensure NSBluetoothAlwaysUsageDescription is set in Info.plist.")
1216
1223
  module?.eddystoneScanPromise?.reject("BLUETOOTH_UNAUTHORIZED", "Bluetooth permission denied")
1217
1224
  module?.eddystoneScanPromise = nil
1218
1225
  case .poweredOff:
1226
+ print("[ExpoBeacon] Bluetooth is powered off — Eddystone scanning/monitoring unavailable.")
1219
1227
  module?.eddystoneScanPromise?.reject("BLUETOOTH_OFF", "Bluetooth is powered off")
1220
1228
  module?.eddystoneScanPromise = nil
1221
1229
  default:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-beacon",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "description": "Expo module for scanning, pairing, and monitoring iBeacons on Android and iOS",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",