From 50ece1975591a89a75b901c7a0a2d45503cecb50 Mon Sep 17 00:00:00 2001 From: Nan Date: Tue, 27 May 2025 10:03:48 -0700 Subject: [PATCH] fix(badges): Use `hasBadge` flag to indicate badge count is set * This fixes a bug when a notification had "SetTo" = 0; our check for the existence of notification.badge could not differentiate null vs 0, and we detected 0 as lack of existence. * Using a flag let's us differentiate between null vs 0 badge count. The payload from APNS will be already be an NSNumber: https://developer.apple.com/documentation/usernotifications/unnotificationcontent/badge?language=objc and we will set the flag if there is a badge --- iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.h | 3 +++ iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.m | 5 ++++- .../OneSignalExtension/OneSignalExtensionBadgeHandler.m | 2 +- .../OneSignalNotifications/OSNotificationsManager.m | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.h b/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.h index d92422a01..623dcc88a 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.h +++ b/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.h @@ -59,6 +59,9 @@ @property(readonly, nullable)NSString* category; /* The badge assigned to the application icon */ +/// Indicates if badge count is set on this notification; this flag is needed as the `badge` property is an +/// integer primitive and cannot be used to differentiate between null badge vs badge count of 0. +@property(readonly)BOOL hasBadge; @property(readonly)NSInteger badge; @property(readonly)NSInteger badgeIncrement; diff --git a/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.m b/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.m index 141b1e85a..4c00a980b 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.m +++ b/iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.m @@ -124,6 +124,7 @@ - (void)parseCommonOneSignalFields:(NSDictionary*)payload { - (void)parseApnsFields { [self parseAlertField:_rawPayload[@"aps"][@"alert"]]; + _hasBadge = _rawPayload[@"aps"][@"badge"] ? true : false; _badge = [_rawPayload[@"aps"][@"badge"] intValue]; _sound = _rawPayload[@"aps"][@"sound"]; } @@ -257,7 +258,9 @@ - (NSDictionary *)jsonRepresentation { if (self.templateId) [obj setObject:self.templateId forKeyedSubscript: @"templateId"]; - if (self.badge) + [obj setObject:@(self.hasBadge) forKeyedSubscript: @"hasBadge"]; + + if (self.hasBadge) [obj setObject:@(self.badge) forKeyedSubscript: @"badge"]; if (self.badgeIncrement) diff --git a/iOS_SDK/OneSignalSDK/OneSignalExtension/OneSignalExtensionBadgeHandler.m b/iOS_SDK/OneSignalSDK/OneSignalExtension/OneSignalExtensionBadgeHandler.m index d9b076b4a..0e5097b70 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalExtension/OneSignalExtensionBadgeHandler.m +++ b/iOS_SDK/OneSignalSDK/OneSignalExtension/OneSignalExtensionBadgeHandler.m @@ -34,7 +34,7 @@ + (void)handleBadgeCountWithNotificationRequest:(UNNotificationRequest *)request //if the user is setting the badge directly instead of incrementing/decrementing, //make sure the OneSignal cached value is updated to this value if (!notification.badgeIncrement) { - if (notification.badge) + if (notification.hasBadge) [OneSignalExtensionBadgeHandler updateCachedBadgeValue:notification.badge]; return; diff --git a/iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotificationsManager.m b/iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotificationsManager.m index 9ce51e29b..b8cebda98 100644 --- a/iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotificationsManager.m +++ b/iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotificationsManager.m @@ -985,7 +985,7 @@ + (UNNotificationRequest*)prepareUNNotificationRequest:(OSNotification*)notifica else content.sound = UNNotificationSound.defaultSound; - if (notification.badge != 0) + if (notification.hasBadge) content.badge = [NSNumber numberWithInteger:notification.badge]; // Check if media attached