diff --git a/packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm b/packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm index 8b3be6bccc33..d5c6bc7270a0 100644 --- a/packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm +++ b/packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.mm @@ -322,7 +322,18 @@ - (void)handleRemoteNotificationRegistrationError:(NSNotification *)notification */ RCT_EXPORT_METHOD(setApplicationIconBadgeNumber : (double)number) { - RCTSharedApplication().applicationIconBadgeNumber = number; + NSInteger badgeCount = (NSInteger)lround(number); + if (@available(iOS 16.0, *)) { + [UNUserNotificationCenter.currentNotificationCenter + setBadgeCount:badgeCount + withCompletionHandler:^(NSError *_Nullable error) { + if (error != nil) { + RCTLogWarn(@"Failed to set application icon badge number: %@", error); + } + }]; + } else { + RCTSharedApplication().applicationIconBadgeNumber = badgeCount; + } } /** diff --git a/packages/rn-tester/js/examples/PushNotificationIOS/PushNotificationIOSExample.js b/packages/rn-tester/js/examples/PushNotificationIOS/PushNotificationIOSExample.js new file mode 100644 index 000000000000..60d0565ea099 --- /dev/null +++ b/packages/rn-tester/js/examples/PushNotificationIOS/PushNotificationIOSExample.js @@ -0,0 +1,98 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +'use strict'; + +import type {RNTesterModuleExample} from '../../types/RNTesterTypes'; + +import RNTesterText from '../../components/RNTesterText'; +import * as React from 'react'; +import {useCallback, useState} from 'react'; +import {Button, StyleSheet, View} from 'react-native'; +import PushNotificationIOS from 'react-native/Libraries/PushNotificationIOS/PushNotificationIOS'; + +// Fires setApplicationIconBadgeNumber many times back-to-back. +const RAPID_FIRE_COUNT = 50; + +function BadgeExample(): React.Node { + const [reported, setReported] = useState(null); + + const updateBadge = useCallback((n: number) => { + PushNotificationIOS.setApplicationIconBadgeNumber(n); + }, []); + + const readBadge = useCallback(() => { + PushNotificationIOS.getApplicationIconBadgeNumber((n: number) => { + setReported(n); + }); + }, []); + + const rapidFire = useCallback(() => { + for (let i = 1; i <= RAPID_FIRE_COUNT; i++) { + PushNotificationIOS.setApplicationIconBadgeNumber(i); + } + }, []); + + return ( + + + {reported == null + ? 'Tap "Read current badge" to query the badge number.' + : `Last read badge number: ${reported}`} + + +