learning_ai_common_plat/packages/swift-platform-sdk/Sources/BLKillSwitchClient.swift
saravanakumardb1 77d6ff328f fix(swift-sdk): URL-encode license key + add request tracing to kill switch
BLLicenseClient.checkStatus: percent-encode key before inserting into URL
path to prevent malformed URLs with special characters.

BLKillSwitchClient: add X-Product-Id and X-Request-Id headers for
consistency with BLPlatformClient request tracing pattern.
2026-02-28 22:52:00 -08:00

61 lines
2.3 KiB
Swift

// Kill Switch Client
// Checks platform-service kill switch at app launch.
// If the app is disabled server-side, surfaces a maintenance message.
// Fails open network errors allow the app to run.
import Foundation
/// Generic kill switch client for all ByteLyst iOS apps.
/// Checks GET /api/settings/kill-switch?productId=X at launch.
public final class BLKillSwitchClient {
private let config: BLPlatformConfig
/// Whether the app is disabled by the server.
public private(set) var isDisabled = false
/// Maintenance message from the server (empty if not disabled).
public private(set) var maintenanceMessage = ""
public init(config: BLPlatformConfig) {
self.config = config
}
/// Check kill switch status. Non-blocking defaults to enabled on failure (fail open).
public func check() async {
guard let url = URL(string: "\(config.baseURL)/api/settings/kill-switch?productId=\(config.productId)") else { return }
var request = URLRequest(url: url)
request.timeoutInterval = 5
request.setValue(config.productId, forHTTPHeaderField: "X-Product-Id")
request.setValue(UUID().uuidString, forHTTPHeaderField: "X-Request-Id")
do {
let (data, response) = try await URLSession.shared.data(for: request)
guard let http = response as? HTTPURLResponse, http.statusCode == 200 else { return }
struct KillSwitchResponse: Codable {
let enabled: Bool?
let disabled: Bool?
let message: String?
}
let result = try JSONDecoder().decode(KillSwitchResponse.self, from: data)
// Support both `enabled: false` and `disabled: true` patterns
if result.disabled == true || result.enabled == false {
isDisabled = true
maintenanceMessage = result.message ?? "\(config.productId) is temporarily unavailable for maintenance."
}
} catch {
// Network error allow the app to run (fail open)
}
}
/// Reset the kill switch state (e.g. for retry).
public func reset() {
isDisabled = false
maintenanceMessage = ""
}
}