Skip to content

Commit 8a4e9a5

Browse files
SudoPlzmikehardy
andauthored
feat(ios, messaging): add getIsHeadless method to access iOS launch state (#4304)
* Exposed getIsHeadless on the iOS messaging module - Fixes: #4233 * Added platform annotation to method declaration * Added documentation for getIsHeadless * Fixed type typo * Fixed ios isHeadless property * Turned the isHeadless method into a launchedHeadless constant * Apply suggestions from code review * Update packages/messaging/lib/index.d.ts * Revert "Turned the isHeadless method into a launchedHeadless constant" This reverts commit c181528. Co-authored-by: Mike Hardy <[email protected]>
1 parent 02132ce commit 8a4e9a5

File tree

6 files changed

+43
-5
lines changed

6 files changed

+43
-5
lines changed

docs/messaging/usage/index.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,15 @@ RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
295295
initialProperties:appProperties];
296296
```
297297
298+
- For projects that use react-native-navigation (or if you just don't want to mess with your launchProperties) you can use the `getIsHeadless` method (iOS only) from messaging like so:
299+
300+
```jsx
301+
messaging().getIsHeadless().then(isHeadless => {
302+
// do sth with isHeadless
303+
});
304+
305+
```
306+
298307

299308
On Android, the `isHeadless` prop will not exist.
300309

packages/messaging/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
2222
@interface RNFBMessagingNSNotificationCenter : NSObject
2323

2424
+ (_Nonnull instancetype)sharedInstance;
25+
@property (nonatomic) BOOL isHeadless;
2526

2627
@end
2728

packages/messaging/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.m

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#import "RNFBMessaging+FIRMessagingDelegate.h"
2727

2828
@implementation RNFBMessagingNSNotificationCenter
29-
29+
@synthesize isHeadless;
3030
+ (instancetype)sharedInstance {
3131
static dispatch_once_t once;
3232
__strong static RNFBMessagingNSNotificationCenter *sharedInstance;
@@ -135,9 +135,10 @@ - (void)application_onDidFinishLaunchingNotification:(nonnull NSNotification *)n
135135
if (notification.userInfo[UIApplicationLaunchOptionsRemoteNotificationKey]) {
136136
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
137137
if (rctRootView != nil) {
138+
isHeadless = YES;
138139
NSMutableDictionary *appPropertiesDict = rctRootView.appProperties != nil ? [rctRootView.appProperties mutableCopy] : [NSMutableDictionary dictionary];
139140
if([appPropertiesDict objectForKey:@"isHeadless"] != nil && [appPropertiesDict[@"isHeadless"] isEqual:@([RCTConvert BOOL:@(NO)])]) {
140-
appPropertiesDict[@"isHeadless"] = @([RCTConvert BOOL:@(YES)]);
141+
appPropertiesDict[@"isHeadless"] = @([RCTConvert BOOL:@(isHeadless)]);
141142
rctRootView.appProperties = appPropertiesDict;
142143
}
143144
}
@@ -153,19 +154,21 @@ - (void)application_onDidFinishLaunchingNotification:(nonnull NSNotification *)n
153154
#endif
154155
} else {
155156
if (rctRootView != nil) {
157+
isHeadless = NO;
156158
NSMutableDictionary *appPropertiesDict = rctRootView.appProperties != nil ? [rctRootView.appProperties mutableCopy] : [NSMutableDictionary dictionary];
157159
if([appPropertiesDict objectForKey:@"isHeadless"] != nil && [appPropertiesDict[@"isHeadless"] isEqual:@([RCTConvert BOOL:@(YES)])]) {
158-
appPropertiesDict[@"isHeadless"] = @([RCTConvert BOOL:@(NO)]);
160+
appPropertiesDict[@"isHeadless"] = @([RCTConvert BOOL:@(isHeadless)]);
159161
rctRootView.appProperties = appPropertiesDict;
160162
}
161163

162164
}
163165
}
164166
} else {
165167
if (rctRootView != nil) {
168+
isHeadless = NO;
166169
NSMutableDictionary *appPropertiesDict = rctRootView.appProperties != nil ? [rctRootView.appProperties mutableCopy] : [NSMutableDictionary dictionary];
167170
if([appPropertiesDict objectForKey:@"isHeadless"] != nil && [appPropertiesDict[@"isHeadless"] isEqual:@([RCTConvert BOOL:@(YES)])]) {
168-
appPropertiesDict[@"isHeadless"] = @([RCTConvert BOOL:@(NO)]);
171+
appPropertiesDict[@"isHeadless"] = @([RCTConvert BOOL:@(isHeadless)]);
169172
rctRootView.appProperties = appPropertiesDict;
170173
}
171174

@@ -182,10 +185,12 @@ - (void)application_onDidEnterForeground {
182185
[[UIApplication sharedApplication].delegate.window.rootViewController.view isKindOfClass:[RCTRootView class]]
183186
) {
184187
RCTRootView *rctRootView = (RCTRootView *) [UIApplication sharedApplication].delegate.window.rootViewController.view;
188+
185189
if (rctRootView.appProperties != nil && rctRootView.appProperties[@"isHeadless"] == @(YES)) {
186190
NSMutableDictionary *appPropertiesDict = [rctRootView.appProperties mutableCopy];
191+
isHeadless = NO;
187192
if([appPropertiesDict objectForKey:@"isHeadless"] != nil && [appPropertiesDict[@"isHeadless"] isEqual:@([RCTConvert BOOL:@(YES)])]) {
188-
appPropertiesDict[@"isHeadless"] = @([RCTConvert BOOL:@(NO)]);
193+
appPropertiesDict[@"isHeadless"] = @([RCTConvert BOOL:@(isHeadless)]);
189194
rctRootView.appProperties = appPropertiesDict;
190195
}
191196
}

packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.m

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#import "RNFBMessagingSerializer.h"
2525
#import "RNFBMessaging+AppDelegate.h"
2626
#import "RNFBMessaging+UNUserNotificationCenter.h"
27+
#import "RNFBMessaging+NSNotificationCenter.h"
2728

2829
@implementation RNFBMessagingModule
2930
#pragma mark -
@@ -164,6 +165,15 @@ - (NSDictionary *)constantsToExport {
164165
}
165166
}
166167

168+
RCT_EXPORT_METHOD(getIsHeadless
169+
:(RCTPromiseResolveBlock) resolve
170+
:(RCTPromiseRejectBlock) reject
171+
) {
172+
RNFBMessagingNSNotificationCenter* notifCenter = [RNFBMessagingNSNotificationCenter sharedInstance];
173+
174+
return resolve(@([RCTConvert BOOL:@(notifCenter.isHeadless)]));
175+
}
176+
167177
RCT_EXPORT_METHOD(requestPermission:
168178
(NSDictionary *) permissions
169179
:(RCTPromiseResolveBlock) resolve

packages/messaging/lib/index.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,15 @@ export namespace FirebaseMessagingTypes {
610610
*/
611611
getToken(authorizedEntity?: string, scope?: string): Promise<string>;
612612

613+
/**
614+
* Returns wether the root view is headless or not
615+
* i.e true if the app was launched in the background (for example, by data-only cloud message)
616+
*
617+
* More info: https://rnfirebase.io/messaging/usage#background-application-state
618+
* @platform ios iOS
619+
*/
620+
getIsHeadless(): Promise<boolean>;
621+
613622
/**
614623
* Removes access to an FCM token previously authorized by it's scope. Messages sent by the server
615624
* to this token will fail.

packages/messaging/lib/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ class FirebaseMessagingModule extends FirebaseModule {
126126
return this.native.getInitialNotification();
127127
}
128128

129+
getIsHeadless() {
130+
return this.native.getIsHeadless();
131+
}
132+
129133
getToken(authorizedEntity, scope) {
130134
if (!isUndefined(authorizedEntity) && !isString(authorizedEntity)) {
131135
throw new Error(

0 commit comments

Comments
 (0)