spotny-sdk 1.0.1 → 1.0.2
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.
|
@@ -42,8 +42,9 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
|
|
|
42
42
|
private var identifierId: String? = null
|
|
43
43
|
|
|
44
44
|
// ── Configuration ─────────────────────────────────────────────────────────
|
|
45
|
-
// backendURL
|
|
45
|
+
// backendURL and apiBasePath are fixed — not overridable by consumers.
|
|
46
46
|
private val backendURL = "https://api.spotny.app"
|
|
47
|
+
private val apiBasePath = "/api/app/sdk"
|
|
47
48
|
private var maxDetectionDistance = 8.0 // metres
|
|
48
49
|
/** Multiplier applied to raw BLE distance. Default 0.5 matches Kontakt.io -12 dBm beacons. */
|
|
49
50
|
private var distanceCorrectionFactor = 0.5
|
|
@@ -171,7 +172,7 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
|
|
|
171
172
|
// Send token + apiKey + identifierId to backend — response returns a JWT used for all subsequent calls
|
|
172
173
|
// sdkToken is null here so no Authorization header is injected on this call
|
|
173
174
|
val verifyPayload = mapOf("token" to token, "api_key" to key, "user_id" to uid)
|
|
174
|
-
post("/
|
|
175
|
+
post("$apiBasePath/verify", verifyPayload) { status, body ->
|
|
175
176
|
when {
|
|
176
177
|
status in 200..299 -> {
|
|
177
178
|
val verifyJson = try { parseJsonObject(body) } catch (_: Exception) { null }
|
|
@@ -448,7 +449,7 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
|
|
|
448
449
|
val credential = sdkCredential ?: return false
|
|
449
450
|
val key = apiKey ?: return false
|
|
450
451
|
return try {
|
|
451
|
-
val conn = (URL("$backendURL/
|
|
452
|
+
val conn = (URL("$backendURL$apiBasePath/verify").openConnection() as HttpURLConnection).apply {
|
|
452
453
|
requestMethod = "POST"
|
|
453
454
|
setRequestProperty("Content-Type", "application/json")
|
|
454
455
|
connectTimeout = 10_000
|
|
@@ -485,7 +486,7 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
|
|
|
485
486
|
) {
|
|
486
487
|
ioExecutor.execute {
|
|
487
488
|
// Auto-refresh JWT before every call except verify itself
|
|
488
|
-
if (endpoint != "/
|
|
489
|
+
if (endpoint != "$apiBasePath/verify" && isTokenExpired()) {
|
|
489
490
|
if (!refreshJWTBlocking()) {
|
|
490
491
|
reactContext.runOnUiQueueThread { completion(-1, "") }
|
|
491
492
|
return@execute
|
|
@@ -547,7 +548,7 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
|
|
|
547
548
|
|
|
548
549
|
val payload = mutableMapOf<String, Any?>("beacon_id" to key)
|
|
549
550
|
|
|
550
|
-
post("/
|
|
551
|
+
post("$apiBasePath/distribute", payload) { status, body ->
|
|
551
552
|
fetchInProgress[key] = false
|
|
552
553
|
if (status != 200) {
|
|
553
554
|
Log.w(TAG, "Campaign fetch status $status for beacon $key")
|
|
@@ -639,10 +640,10 @@ class SpotnySdkModule(private val reactContext: ReactApplicationContext) :
|
|
|
639
640
|
}
|
|
640
641
|
|
|
641
642
|
private fun sendProximity(eventType: String, key: String, distance: Double) =
|
|
642
|
-
sendTracking(eventType, key, distance, "/
|
|
643
|
+
sendTracking(eventType, key, distance, "$apiBasePath/proximity")
|
|
643
644
|
|
|
644
645
|
private fun sendImpression(key: String, distance: Double) =
|
|
645
|
-
sendTracking("IMPRESSION_HEARTBEAT", key, distance, "/
|
|
646
|
+
sendTracking("IMPRESSION_HEARTBEAT", key, distance, "$apiBasePath/track")
|
|
646
647
|
|
|
647
648
|
// ── Minimal JSON parser (avoids org.json / GSON dependency) ──────────────
|
|
648
649
|
// Only handles flat and one-level-deep objects. For this SDK, that is enough.
|
|
@@ -54,6 +54,7 @@ public class SpotnyBeaconScanner: NSObject {
|
|
|
54
54
|
// ── Configuration ────────────────────────────────────────────────────────────
|
|
55
55
|
// backendURL and kontaktAPIKey are fixed — not overridable by consumers.
|
|
56
56
|
private let backendURL: String = "https://api.spotny.app"
|
|
57
|
+
private let apiBasePath: String = "/api/app/sdk"
|
|
57
58
|
private let kontaktAPIKey: String = "mgrz08TOKNHafeY02cWIs9mxUHbynNQJ"
|
|
58
59
|
private var maxDetectionDistance: Double = 8.0
|
|
59
60
|
/// Multiplier applied to raw RSSI-derived distance to compensate for low TX power.
|
|
@@ -244,8 +245,8 @@ public class SpotnyBeaconScanner: NSObject {
|
|
|
244
245
|
|
|
245
246
|
// Send token + apiKey + identifierId to backend — response returns a JWT used for all subsequent calls
|
|
246
247
|
// sdkToken is nil here so no Authorization header is injected on this call
|
|
247
|
-
let verifyPayload: [String: Any] = ["token": token, "api_key": key, "
|
|
248
|
-
post(endpoint: "/
|
|
248
|
+
let verifyPayload: [String: Any] = ["token": token, "api_key": key, "identifier_id": uid]
|
|
249
|
+
post(endpoint: "\(apiBasePath)/verify", payload: verifyPayload) { [weak self] result in
|
|
249
250
|
guard let self = self else { return }
|
|
250
251
|
switch result {
|
|
251
252
|
case .success(let (status, data)):
|
|
@@ -499,8 +500,8 @@ public class SpotnyBeaconScanner: NSObject {
|
|
|
499
500
|
return
|
|
500
501
|
}
|
|
501
502
|
jwtRefreshInProgress = true
|
|
502
|
-
let refreshPayload: [String: Any] = ["token": credential, "api_key": key, "
|
|
503
|
-
performPost(endpoint: "/
|
|
503
|
+
let refreshPayload: [String: Any] = ["token": credential, "api_key": key, "identifier_id": identifierId ?? ""]
|
|
504
|
+
performPost(endpoint: "\(apiBasePath)/verify", payload: refreshPayload) { [weak self] result in
|
|
504
505
|
guard let self = self else { return }
|
|
505
506
|
let flush: (Error?) -> Void = { err in
|
|
506
507
|
let queue = self.jwtRefreshQueue
|
|
@@ -542,7 +543,7 @@ public class SpotnyBeaconScanner: NSObject {
|
|
|
542
543
|
payload: [String: Any],
|
|
543
544
|
completion: @escaping (Result<(Int, Data), Error>) -> Void
|
|
544
545
|
) {
|
|
545
|
-
guard endpoint == "/
|
|
546
|
+
guard endpoint == "\(apiBasePath)/verify" || !isTokenExpired() else {
|
|
546
547
|
refreshJWT { [weak self] error in
|
|
547
548
|
if let error = error { completion(.failure(error)); return }
|
|
548
549
|
self?.performPost(endpoint: endpoint, payload: payload, completion: completion)
|
|
@@ -615,7 +616,7 @@ public class SpotnyBeaconScanner: NSObject {
|
|
|
615
616
|
|
|
616
617
|
let payload: [String: Any] = ["beacon_id": key]
|
|
617
618
|
|
|
618
|
-
post(endpoint: "/
|
|
619
|
+
post(endpoint: "\(apiBasePath)/distribute", payload: payload) { [weak self] result in
|
|
619
620
|
guard let self = self else { return }
|
|
620
621
|
defer { self.fetchInProgress[key] = false }
|
|
621
622
|
|
|
@@ -726,12 +727,12 @@ public class SpotnyBeaconScanner: NSObject {
|
|
|
726
727
|
|
|
727
728
|
private func sendProximity(eventType: String, key: String, distance: Double) {
|
|
728
729
|
sendTracking(eventType: eventType, key: key, distance: distance,
|
|
729
|
-
endpoint: "/
|
|
730
|
+
endpoint: "\(apiBasePath)/proximity")
|
|
730
731
|
}
|
|
731
732
|
|
|
732
733
|
private func sendImpression(key: String, distance: Double) {
|
|
733
734
|
sendTracking(eventType: "IMPRESSION_HEARTBEAT", key: key, distance: distance,
|
|
734
|
-
endpoint: "/
|
|
735
|
+
endpoint: "\(apiBasePath)/track")
|
|
735
736
|
}
|
|
736
737
|
|
|
737
738
|
// MARK: - State Cleanup
|