Skip to content

Commit b20caa9

Browse files
authored
Merge pull request #1568 from OneSignal/fix/drop_applicationIconBadgeNumber_usage
fix(badges): drop deprecated applicationIconBadgeNumber usage
2 parents 48dd3f4 + 1fe4fc1 commit b20caa9

File tree

12 files changed

+128
-23
lines changed

12 files changed

+128
-23
lines changed

iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@
7373
3C277D7E2BD76E0000857606 /* OSIdentityModelRepo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C277D7D2BD76E0000857606 /* OSIdentityModelRepo.swift */; };
7474
3C2C7DC8288F3C020020F9AE /* OSSubscriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C2C7DC7288F3C020020F9AE /* OSSubscriptionModel.swift */; };
7575
3C2D8A5928B4C4E300BE41F6 /* OSDelta.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C2D8A5828B4C4E300BE41F6 /* OSDelta.swift */; };
76+
3C2DB2F12DE6CB5E0006B905 /* OneSignalBadgeHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C2DB2EF2DE6CB5E0006B905 /* OneSignalBadgeHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; };
77+
3C2DB2F22DE6CB5E0006B905 /* OneSignalBadgeHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 3C2DB2F02DE6CB5E0006B905 /* OneSignalBadgeHelpers.m */; };
7678
3C44673E296D099D0039A49E /* OneSignalMobileProvision.m in Sources */ = {isa = PBXBuildFile; fileRef = 912411FD1E73342200E41FD7 /* OneSignalMobileProvision.m */; };
7779
3C44673F296D09CC0039A49E /* OneSignalMobileProvision.h in Headers */ = {isa = PBXBuildFile; fileRef = 912411FC1E73342200E41FD7 /* OneSignalMobileProvision.h */; settings = {ATTRIBUTES = (Public, ); }; };
7880
3C448B9D2936ADFD002F96BC /* OSBackgroundTaskHandlerImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C448B9B2936ADFD002F96BC /* OSBackgroundTaskHandlerImpl.h */; };
@@ -1251,6 +1253,8 @@
12511253
3C2C7DC2288E007E0020F9AE /* UnitTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UnitTests-Bridging-Header.h"; sourceTree = "<group>"; };
12521254
3C2C7DC7288F3C020020F9AE /* OSSubscriptionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSSubscriptionModel.swift; sourceTree = "<group>"; };
12531255
3C2D8A5828B4C4E300BE41F6 /* OSDelta.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSDelta.swift; sourceTree = "<group>"; };
1256+
3C2DB2EF2DE6CB5E0006B905 /* OneSignalBadgeHelpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OneSignalBadgeHelpers.h; sourceTree = "<group>"; };
1257+
3C2DB2F02DE6CB5E0006B905 /* OneSignalBadgeHelpers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OneSignalBadgeHelpers.m; sourceTree = "<group>"; };
12541258
3C448B9B2936ADFD002F96BC /* OSBackgroundTaskHandlerImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSBackgroundTaskHandlerImpl.h; sourceTree = "<group>"; };
12551259
3C448B9C2936ADFD002F96BC /* OSBackgroundTaskHandlerImpl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OSBackgroundTaskHandlerImpl.m; sourceTree = "<group>"; };
12561260
3C448BA12936B474002F96BC /* OSBackgroundTaskManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSBackgroundTaskManager.swift; sourceTree = "<group>"; };
@@ -2596,6 +2600,8 @@
25962600
DE7D182C270273B0002D3A5D /* OSNotification.h */,
25972601
454F94F41FAD2E5A00D74CCF /* OSNotification.m */,
25982602
454F94F61FAD2EC300D74CCF /* OSNotification+Internal.h */,
2603+
3C2DB2EF2DE6CB5E0006B905 /* OneSignalBadgeHelpers.h */,
2604+
3C2DB2F02DE6CB5E0006B905 /* OneSignalBadgeHelpers.m */,
25992605
3CE8CC4C2911ADD1000DB0D3 /* OSDeviceUtils.h */,
26002606
3C47A972292642B100312125 /* OneSignalConfigManager.h */,
26012607
3C47A973292642B100312125 /* OneSignalConfigManager.m */,
@@ -3138,6 +3144,7 @@
31383144
DE7D182F270275FF002D3A5D /* OneSignalTrackFirebaseAnalytics.h in Headers */,
31393145
DEF7845C2912E89200A1F3A5 /* OSObservable.h in Headers */,
31403146
DE7D1875270375FF002D3A5D /* OSReattemptRequest.h in Headers */,
3147+
3C2DB2F12DE6CB5E0006B905 /* OneSignalBadgeHelpers.h in Headers */,
31413148
DEF784652912FB2200A1F3A5 /* OSDialogInstanceManager.h in Headers */,
31423149
DEF78493291479B200A1F3A5 /* OneSignalSelectorHelpers.h in Headers */,
31433150
DE7D1862270374EE002D3A5D /* OSJSONHandling.h in Headers */,
@@ -4427,6 +4434,7 @@
44274434
DEF784642912FA5100A1F3A5 /* OSDialogInstanceManager.m in Sources */,
44284435
DE7D183B27027EFC002D3A5D /* NSURL+OneSignal.m in Sources */,
44294436
DE7D186B270374EE002D3A5D /* OneSignalRequest.m in Sources */,
4437+
3C2DB2F22DE6CB5E0006B905 /* OneSignalBadgeHelpers.m in Sources */,
44304438
3C44673E296D099D0039A49E /* OneSignalMobileProvision.m in Sources */,
44314439
3CCF44BF299B17290021964D /* OneSignalWrapper.m in Sources */,
44324440
DEF78492291479B200A1F3A5 /* OneSignalSelectorHelpers.m in Sources */,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Modified MIT License
3+
*
4+
* Copyright 2025 OneSignal
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* 1. The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* 2. All copies of substantial portions of the Software may only be used in connection
17+
* with services provided by OneSignal.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#import <Foundation/Foundation.h>
29+
30+
@interface OneSignalBadgeHelpers : NSObject
31+
+ (void)updateCachedBadgeValue:(NSInteger)value usePreviousBadgeCount:(BOOL)usePrevious;
32+
@end
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* Modified MIT License
3+
*
4+
* Copyright 2025 OneSignal
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* 1. The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* 2. All copies of substantial portions of the Software may only be used in connection
17+
* with services provided by OneSignal.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#import "OneSignalBadgeHelpers.h"
29+
#import "OneSignalUserDefaults.h"
30+
#import "OneSignalCommonDefines.h"
31+
32+
@implementation OneSignalBadgeHelpers
33+
34+
/**
35+
Store a previous badge count so that we can revert to this cached value when a notification display is cancelled.
36+
When `usePreviousBadgeCount` is `true`, the `value` passed to this method will be unused.
37+
*/
38+
+ (void)updateCachedBadgeValue:(NSInteger)value usePreviousBadgeCount:(BOOL)usePrevious {
39+
// Since badge logic can be executed in an extension, we need to use app groups to get
40+
// a shared NSUserDefaults from the app group suite name
41+
if (usePrevious) {
42+
// Keep the PREVIOUS_ONESIGNAL_BADGE_KEY value unchanged
43+
NSInteger previousBadgeCount = [OneSignalUserDefaults.initShared getSavedIntegerForKey:PREVIOUS_ONESIGNAL_BADGE_KEY defaultValue:0];
44+
[OneSignalUserDefaults.initShared saveIntegerForKey:ONESIGNAL_BADGE_KEY withValue:previousBadgeCount];
45+
} else {
46+
NSInteger previousBadgeCount = [OneSignalUserDefaults.initShared getSavedIntegerForKey:ONESIGNAL_BADGE_KEY defaultValue:0];
47+
[OneSignalUserDefaults.initShared saveIntegerForKey:PREVIOUS_ONESIGNAL_BADGE_KEY withValue:previousBadgeCount];
48+
[OneSignalUserDefaults.initShared saveIntegerForKey:ONESIGNAL_BADGE_KEY withValue:value];
49+
}
50+
}
51+
52+
@end

iOS_SDK/OneSignalSDK/OneSignalCore/Source/OneSignalCommonDefines.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@
159159
#define ONESIGNAL_DISABLE_BADGE_CLEARING @"OneSignal_disable_badge_clearing"
160160
#define ONESIGNAL_APP_GROUP_NAME_KEY @"OneSignal_app_groups_key"
161161
#define ONESIGNAL_BADGE_KEY @"onesignalBadgeCount"
162+
/// Store the previous badge count to read for a cancelled notification display event
163+
#define PREVIOUS_ONESIGNAL_BADGE_KEY @"previousOnesignalBadgeCount"
162164

163165
// Firebase
164166
#define ONESIGNAL_FB_ENABLE_FIREBASE @"OS_ENABLE_FIREBASE_ANALYTICS"

iOS_SDK/OneSignalSDK/OneSignalCore/Source/OneSignalCore.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
#import <OneSignalCore/OSLocation.h>
5959
#import <OneSignalCore/OSBundleUtils.h>
6060
#import <OneSignalCore/OneSignalClientError.h>
61+
#import <OneSignalCore/OneSignalBadgeHelpers.h>
6162

6263
// TODO: Testing: Should this class be defined in this file?
6364
@interface OneSignalCoreImpl : NSObject

iOS_SDK/OneSignalSDK/OneSignalExtension/OneSignalExtensionBadgeHandler.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,4 @@
3131

3232
@interface OneSignalExtensionBadgeHandler : NSObject
3333
+ (void)handleBadgeCountWithNotificationRequest:(UNNotificationRequest *)request withNotification:(OSNotification *)notification withMutableNotificationContent:(UNMutableNotificationContent *)replacementContent;
34-
+ (void)updateCachedBadgeValue:(NSInteger)value;
35-
+ (NSInteger)currentCachedBadgeValue;
3634
@end

iOS_SDK/OneSignalSDK/OneSignalExtension/OneSignalExtensionBadgeHandler.m

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ + (void)handleBadgeCountWithNotificationRequest:(UNNotificationRequest *)request
3535
//make sure the OneSignal cached value is updated to this value
3636
if (!notification.badgeIncrement) {
3737
if (notification.hasBadge)
38-
[OneSignalExtensionBadgeHandler updateCachedBadgeValue:notification.badge];
38+
[OneSignalBadgeHelpers updateCachedBadgeValue:notification.badge usePreviousBadgeCount:false];
3939

4040
return;
4141
}
@@ -50,17 +50,11 @@ + (void)handleBadgeCountWithNotificationRequest:(UNNotificationRequest *)request
5050

5151
replacementContent.badge = @(currentValue);
5252

53-
[OneSignalExtensionBadgeHandler updateCachedBadgeValue:currentValue];
53+
[OneSignalBadgeHelpers updateCachedBadgeValue:currentValue usePreviousBadgeCount:false];
5454
}
5555

5656
+ (NSInteger)currentCachedBadgeValue {
5757
return [OneSignalUserDefaults.initShared getSavedIntegerForKey:ONESIGNAL_BADGE_KEY defaultValue:0];
5858
}
5959

60-
+ (void)updateCachedBadgeValue:(NSInteger)value {
61-
// Since badge logic can be executed in an extension, we need to use app groups to get
62-
// a shared NSUserDefaults from the app group suite name
63-
[OneSignalUserDefaults.initShared saveIntegerForKey:ONESIGNAL_BADGE_KEY withValue:value];
64-
}
65-
6660
@end

iOS_SDK/OneSignalSDK/OneSignalNotifications/Categories/UNUserNotificationCenter+OneSignalNotifications.m

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ + (void)swizzleSelectors {
9797
[OneSignalNotificationsUNUserNotificationCenter class],
9898
@selector(onesignalGetNotificationSettingsWithCompletionHandler:)
9999
);
100+
injectSelector(
101+
[UNUserNotificationCenter class],
102+
@selector(setBadgeCount:withCompletionHandler:),
103+
[OneSignalNotificationsUNUserNotificationCenter class],
104+
@selector(onesignalSetBadgeCount:withCompletionHandler:)
105+
);
100106
}
101107

102108
+ (void)registerDelegate {
@@ -167,6 +173,15 @@ - (void)onesignalGetNotificationSettingsWithCompletionHandler:(void(^)(UNNotific
167173
[self onesignalGetNotificationSettingsWithCompletionHandler:wrapperBlock];
168174
}
169175

176+
/**
177+
In order for the badge count to be consistent even in situations where the developer manually sets the badge number,
178+
we swizzle the 'setBadgeCount()' method for ios 16+ to intercept these calls so we always know the latest count. This is especially
179+
necessary as there is no equivalent "getBadgeCount" method available.
180+
*/
181+
- (void)onesignalSetBadgeCount:(NSInteger)badge withCompletionHandler:(void(^)(NSError *error))completionHandler {
182+
[OneSignalBadgeHelpers updateCachedBadgeValue:badge usePreviousBadgeCount:false];
183+
[self onesignalSetBadgeCount:badge withCompletionHandler:completionHandler];
184+
}
170185

171186
// A Set to keep track of which classes we have already swizzled so we only
172187
// swizzle each one once. If we swizzled more than once then this will create

iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotification+OneSignal.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ - (void)complete:(OSDisplayableNotification *)notification {
7676
reset the badge count to the value prior to receipt of this notif
7777
*/
7878
if (!notification) {
79-
NSInteger previousBadgeCount = [UIApplication sharedApplication].applicationIconBadgeNumber;
80-
[OneSignalUserDefaults.initShared saveIntegerForKey:ONESIGNAL_BADGE_KEY withValue:previousBadgeCount];
79+
// The badge count value of -99 will not be used, the previous badge count will be set
80+
[OneSignalBadgeHelpers updateCachedBadgeValue:-99 usePreviousBadgeCount:true];
8181
}
8282
if (_completion) {
8383
_completion(notification);

iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotificationsManager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ NS_SWIFT_NAME(onClick(event:));
114114

115115
+ (void)handleWillShowInForegroundForNotification:(OSNotification *_Nonnull)notification completion:(OSNotificationDisplayResponse _Nonnull)completion;
116116
+ (void)handleNotificationActionWithUrl:(NSString* _Nullable)url actionID:(NSString* _Nonnull)actionID;
117-
+ (BOOL)clearBadgeCount:(BOOL)fromNotifOpened fromClearAll:(BOOL)fromClearAll;
117+
+ (void)clearBadgeCount:(BOOL)fromNotifOpened fromClearAll:(BOOL)fromClearAll;
118118

119119
+ (BOOL)receiveRemoteNotification:(UIApplication* _Nonnull)application UserInfo:(NSDictionary* _Nonnull)userInfo completionHandler:(void (^_Nonnull)(UIBackgroundFetchResult))completionHandler;
120120
+ (void)notificationReceived:(NSDictionary* _Nonnull)messageDict wasOpened:(BOOL)opened;

0 commit comments

Comments
 (0)