Add smart device token caching for push notification registration
Cache device token in UserDefaults and only register with backend when token changes. Also registers when app returns from background if token differs from cached value, reducing unnecessary API calls. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,14 @@ class PushNotificationManager: NSObject, ObservableObject {
|
||||
@Published var deviceToken: String?
|
||||
@Published var notificationPermissionGranted = false
|
||||
|
||||
private let registeredTokenKey = "com.casera.registeredDeviceToken"
|
||||
|
||||
/// The last token that was successfully registered with the backend
|
||||
private var lastRegisteredToken: String? {
|
||||
get { UserDefaults.standard.string(forKey: registeredTokenKey) }
|
||||
set { UserDefaults.standard.set(newValue, forKey: registeredTokenKey) }
|
||||
}
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
}
|
||||
@@ -58,12 +66,48 @@ class PushNotificationManager: NSObject, ObservableObject {
|
||||
|
||||
// MARK: - Backend Registration
|
||||
|
||||
private func registerDeviceWithBackend(token: String) async {
|
||||
/// Call this after login to register any pending device token
|
||||
func registerDeviceAfterLogin() {
|
||||
guard let token = deviceToken else {
|
||||
print("⚠️ No device token available for registration")
|
||||
return
|
||||
}
|
||||
|
||||
Task {
|
||||
await registerDeviceWithBackend(token: token, force: false)
|
||||
}
|
||||
}
|
||||
|
||||
/// Call this when app returns from background to check and register if needed
|
||||
func checkAndRegisterDeviceIfNeeded() {
|
||||
guard let token = deviceToken else {
|
||||
print("⚠️ No device token available for registration check")
|
||||
return
|
||||
}
|
||||
|
||||
// Skip if token hasn't changed
|
||||
if token == lastRegisteredToken {
|
||||
print("📱 Device token unchanged, skipping registration")
|
||||
return
|
||||
}
|
||||
|
||||
Task {
|
||||
await registerDeviceWithBackend(token: token, force: false)
|
||||
}
|
||||
}
|
||||
|
||||
private func registerDeviceWithBackend(token: String, force: Bool = false) async {
|
||||
guard TokenStorage.shared.getToken() != nil else {
|
||||
print("⚠️ No auth token available, will register device after login")
|
||||
return
|
||||
}
|
||||
|
||||
// Skip if token hasn't changed (unless forced)
|
||||
if !force && token == lastRegisteredToken {
|
||||
print("📱 Device token unchanged, skipping registration")
|
||||
return
|
||||
}
|
||||
|
||||
// Get unique device identifier
|
||||
let deviceId = await MainActor.run {
|
||||
UIDevice.current.identifierForVendor?.uuidString ?? UUID().uuidString
|
||||
@@ -84,6 +128,10 @@ class PushNotificationManager: NSObject, ObservableObject {
|
||||
|
||||
if let success = result as? ApiResultSuccess<DeviceRegistrationResponse> {
|
||||
print("✅ Device registered successfully: \(success.data)")
|
||||
// Cache the token on successful registration
|
||||
await MainActor.run {
|
||||
self.lastRegisteredToken = token
|
||||
}
|
||||
} else if let error = result as? ApiResultError {
|
||||
print("❌ Failed to register device: \(error.message)")
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user