Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ios): handle incoming and delivered events for remote notifications #229

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions ios/NotifeeCore/NotifeeCore+NSNotificationCenter.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#import <UIKit/UIKit.h>
#import "NotifeeCore+NSNotificationCenter.h"
#import "NotifeeCore+UNUserNotificationCenter.h"
#import "NotifeeCoreDelegateHolder.h"
#import "NotifeeCoreUtil.h"

@implementation NotifeeCoreNSNotificationCenter

Expand Down Expand Up @@ -65,8 +67,31 @@ - (void)application_onDidFinishLaunchingNotification:(nonnull NSNotification *)n
[[NotifeeCoreUNUserNotificationCenter instance] observe];
}

- (void)messaging_didReceiveRemoteNotification:(nonnull NSNotification *)notification {
// update me with logic
//
- (void)messaging_didReceiveRemoteNotification:(nonnull NSDictionary *)userInfo {
if ([NotifeeCoreUtil isAppExtension]) {
return;
}

UIApplication *application = (UIApplication *)[NotifeeCoreUtil notifeeUIApplication];

if (application.applicationState == UIApplicationStateActive) {
if (userInfo[@"aps"][@"alert"] == nil) {
NSDictionary *notifeeNotification = userInfo[kNotifeeUserInfoNotification];

// handle notification outside of notifee
if (notifeeNotification == nil) {
// TODO: parse user info
}

[[NotifeeCoreDelegateHolder instance] didReceiveNotifeeCoreEvent:@{
@"type" : @(NotifeeCoreEventTypeIncoming),
@"detail" : @{
// @"notification" : @"2",
}
}];
}
}
}

@end
27 changes: 22 additions & 5 deletions ios/NotifeeCore/NotifeeCore+UNUserNotificationCenter.m
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center
NSDictionary *notifeeNotification =
notification.request.content.userInfo[kNotifeeUserInfoNotification];

// handle notification outside of notifee
if (notifeeNotification == nil) {
notifeeNotification = [NotifeeCoreUtil parseUNNotificationRequest:notification.request];
}

// we only care about notifications created through notifee
if (notifeeNotification != nil) {
UNNotificationPresentationOptions presentationOptions = UNNotificationPresentationOptionNone;
Expand All @@ -106,9 +111,16 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center
presentationOptions |= UNNotificationPresentationOptionAlert;
}

NSDictionary *notifeeTrigger = notification.request.content.userInfo[kNotifeeUserInfoTrigger];
if (notifeeTrigger != nil) {
// post DELIVERED event
BOOL presented = presentationOptions != UNNotificationPresentationOptionNone;

if (!presented) {
[[NotifeeCoreDelegateHolder instance] didReceiveNotifeeCoreEvent:@{
@"type" : @(NotifeeCoreEventTypeIncoming),
@"detail" : @{
@"notification" : notifeeNotification,
}
}];
} else {
[[NotifeeCoreDelegateHolder instance] didReceiveNotifeeCoreEvent:@{
@"type" : @(NotifeeCoreEventTypeDelivered),
@"detail" : @{
Expand All @@ -118,7 +130,6 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center
}

completionHandler(presentationOptions);

} else if (_originalDelegate != nil && originalUNCDelegateRespondsTo.willPresentNotification) {
[_originalDelegate userNotificationCenter:center
willPresentNotification:notification
Expand All @@ -136,7 +147,13 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center
NSDictionary *notifeeNotification =
response.notification.request.content.userInfo[kNotifeeUserInfoNotification];

// we only care about notifications created through notifee
// handle notification outside of notifee
if (notifeeNotification == nil) {
notifeeNotification =
[NotifeeCoreUtil parseUNNotificationRequest:response.notification.request];
}

// handle notification
if (notifeeNotification != nil) {
if ([response.actionIdentifier isEqualToString:UNNotificationDismissActionIdentifier]) {
// post DISMISSED event, only triggers if notification has a categoryId
Expand Down
1 change: 1 addition & 0 deletions ios/NotifeeCore/NotifeeCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ typedef NS_ENUM(NSInteger, NotifeeCoreEventType) {
NotifeeCoreEventTypeDismissed = 0,
NotifeeCoreEventTypeDelivered = 3,
NotifeeCoreEventTypeTriggerNotificationCreated = 7,
NotifeeCoreEventTypeIncoming = 8,
};

@class NotifeeCore;
Expand Down
3 changes: 2 additions & 1 deletion ios/NotifeeCore/NotifeeCore.m
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ + (void)displayNotification:(NSDictionary *)notification withBlock:(notifeeMetho

[center addNotificationRequest:request
withCompletionHandler:^(NSError *error) {
if (error == nil) {
UIApplication *application = (UIApplication *)[NotifeeCoreUtil notifeeUIApplication];
if (error == nil && application.applicationState != UIApplicationStateActive) {
[[NotifeeCoreDelegateHolder instance] didReceiveNotifeeCoreEvent:@{
@"type" : @(NotifeeCoreEventTypeDelivered),
@"detail" : @{
Expand Down
1 change: 1 addition & 0 deletions ios/NotifeeCore/NotifeeCoreUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN

static NSString *kNotifeeUserInfoNotification = @"__notifee_notification";
static NSString *kNotifeeUserInfoTrigger = @"__notifee_trigger";
static NSString *kNotifeeUserInfoNotifee = @"notifee";

// TimeUnit constants for IntervalTrigger
static NSString *kNotifeeCoreTimeUnitSeconds = @"SECONDS";
Expand Down
90 changes: 76 additions & 14 deletions ios/NotifeeCore/NotifeeCoreUtil.m
Original file line number Diff line number Diff line change
Expand Up @@ -572,17 +572,59 @@ + (NSNumber *)convertToTimestamp:(NSDate *)date {
}

/**
* Parse UNNotificationRequest to NSDictionary
* Parse UNNotificationRequest to NSMutableDictionary
* Used by `getDeliveredNotification`
*
* @param request UNNotificationRequest
*/
+ (NSDictionary *)parseUNNotificationRequest:(UNNotificationRequest *)request {
+ (NSMutableDictionary *)parseUNNotificationRequest:(UNNotificationRequest *)request {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
NSMutableDictionary *iosDict = [NSMutableDictionary dictionary];

dictionary = [self parseUNNotificationContent:request.content];
dictionary[@"id"] = request.identifier;

UNNotificationContent *content = request.content;
NSDictionary *userInfo = request.content.userInfo;

// Check for remote details
if ([request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
NSMutableDictionary *remote = [NSMutableDictionary dictionary];

remote[@"messageId"] = userInfo[@"gcm.message_id"];
remote[@"senderId"] = userInfo[@"google.c.sender.id"];

if (userInfo[@"aps"] != nil) {
remote[@"mutableContent"] = userInfo[@"aps"][@"mutable-content"];
remote[@"contentAvailable"] = userInfo[@"aps"][@"content-available"];
}

dictionary[@"remote"] = remote;
}

dictionary[@"data"] = [self parseDataFromUserInfo:userInfo];

return dictionary;
}

+ (NSMutableDictionary *)parseDataFromUserInfo:(NSDictionary *)userInfo {
NSMutableDictionary *data = [[NSMutableDictionary alloc] init];
for (id key in userInfo) {
// build data dict from remaining keys but skip keys that shouldn't be included in data
if ([key isEqualToString:@"aps"] || [key hasPrefix:@"gcm."] || [key hasPrefix:@"google."] ||
// notifee or notifee_options
[key hasPrefix:@"notifee"] ||
// fcm_options
[key hasPrefix:@"fcm"]) {
continue;
}
data[key] = userInfo[key];
}

return data;
}

+ (NSMutableDictionary *)parseUNNotificationContent:(UNNotificationContent *)content {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
NSMutableDictionary *iosDict = [NSMutableDictionary dictionary];

dictionary[@"subtitle"] = content.subtitle;
dictionary[@"body"] = content.body;
Expand Down Expand Up @@ -627,19 +669,39 @@ + (NSDictionary *)parseUNNotificationRequest:(UNNotificationRequest *)request {
}
}

// TODO: parse sound
// if (content.sound != nil) {
// iosDict[@"sound"] = content.sound;
// }
if (content.attachments != nil) {
// TODO: parse attachments
}

// TODO: parse attachments
// if (content.attachments != nil) {
// iosDict[@"attachments"] =
// [NotifeeCoreUtil DictionaryArrayToNotificationAttachments:content.attachments];
// }
// sound
if (content.sound != nil) {
if ([content.sound isKindOfClass:[NSString class]]) {
iosDict[@"sound"] = content.sound;
} else if ([content.sound isKindOfClass:[NSDictionary class]]) {
NSDictionary *soundDict = content.sound;
NSMutableDictionary *notificationIOSSound = [[NSMutableDictionary alloc] init];

// ios.sound.name String
if (soundDict[@"name"] != nil) {
notificationIOSSound[@"name"] = soundDict[@"name"];
}

dictionary[@"ios"] = iosDict;
// sound.critical Boolean
if (soundDict[@"critical"] != nil) {
notificationIOSSound[@"critical"] = soundDict[@"critical"];
}

// ios.sound.volume Number
if (soundDict[@"volume"] != nil) {
notificationIOSSound[@"volume"] = soundDict[@"volume"];
}

// ios.sound
iosDict[@"sound"] = notificationIOSSound;
}
}

dictionary[@"ios"] = iosDict;
return dictionary;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
<versions>
<version>202108261754</version>
</versions>
<lastUpdated>20211031183710</lastUpdated>
<lastUpdated>20211117172519</lastUpdated>
</versioning>
</metadata>
Original file line number Diff line number Diff line change
@@ -1 +1 @@
f46d250b00cce258968041592579c0b9
3a3b6ee6189ec196640d62aa498d8f83
Original file line number Diff line number Diff line change
@@ -1 +1 @@
82fca979bc80eb6fa59b5c5fec6e992a681f2a26
c5bbcc7268b18c173deff136c47004e63a3e6d25
Original file line number Diff line number Diff line change
@@ -1 +1 @@
95db2cec3f48aedb72c9fbdff61032e755c06acc044f073b906f79a3a9173a03
865fb45e9eef65a7ba7ef6b9cf98c2cd9332078d975380b34f1566be3228b923
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9b95d8e50b6b324e7d7c98ede98d636d67077ebb7024f78c6596887319c2388d6b516300e7a263f1be9f34d5638b7160a74848c6c216aea7d9fc308abff22b48
705ae73ee986c6d7f42f58b3c499f7d3bb8f0ceb64218b2e6a048bb8ecac324967598b7d3620668bfcf774ac50ea7364bbe36d94634e91bd5d6a381bfa5d99ad
2 changes: 1 addition & 1 deletion packages/react-native/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@notifee/react-native",
"version": "3.0.4",
"version": "4.0.0-0",
"author": "Invertase <oss@invertase.io> (http://invertase.io)",
"description": "Notifee - a feature rich notifications library for React Native.",
"main": "dist/index.js",
Expand Down
7 changes: 7 additions & 0 deletions packages/react-native/src/types/Notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,13 @@ export enum EventType {
* Event type is sent when a notification trigger is created.
*/
TRIGGER_NOTIFICATION_CREATED = 7,

/**
* Event type is sent when a notification is incoming - received by the system but not delivered.
*
* This is fired when a remote notification is delivered when the app is in the foreground.
*/
INCOMING = 8,
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request
// [NotifeeExtensionHelper populateNotificationContent:self.bestAttemptContent
// withContentHandler:contentHandler];

[NotifeeExtensionHelper populateNotificationContent:request
withContent:self.bestAttemptContent
withContentHandler:contentHandler];
// [NotifeeExtensionHelper populateNotificationContent:request
// withContent:self.bestAttemptContent
// withContentHandler:contentHandler];
}

- (void)serviceExtensionTimeWillExpire {
Expand Down
2 changes: 1 addition & 1 deletion tests_react_native/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require_relative '../node_modules/@react-native-community/cli-platform-ios/nativ
# with this set to false this will be the same way the user would consume NotifeeCore framework
# Note: you must pod install after changing this value

$NotifeeCoreFromSources = false
$NotifeeCoreFromSources = true
$NotifeeExtension = true


Expand Down
24 changes: 14 additions & 10 deletions tests_react_native/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ PODS:
- nanopb/encode (= 2.30908.0)
- nanopb/decode (2.30908.0)
- nanopb/encode (2.30908.0)
- NotifeeCore (1.0.0)
- PromisesObjC (2.0.0)
- RCT-Folly (2021.06.28.00-v2):
- boost
Expand Down Expand Up @@ -357,12 +358,11 @@ PODS:
- Firebase/Messaging (= 8.8.0)
- React-Core
- RNFBApp
- RNNotifee (3.0.3):
- RNNotifee (4.0.0-0):
- NotifeeCore
- React-Core
- RNNotifeeCore
- RNNotifeeCore (3.0.3):
- RNNotifeeCore/NotifeeCore (= 3.0.3)
- RNNotifeeCore/NotifeeCore (3.0.3)
- RNNotifeeCore (4.0.0-0):
- NotifeeCore
- Yoga (1.14.0)

DEPENDENCIES:
Expand All @@ -374,6 +374,7 @@ DEPENDENCIES:
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- hermes-engine (~> 0.9.0)
- libevent (~> 2.1.12)
- NotifeeCore (from `../../ios`)
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
Expand Down Expand Up @@ -435,6 +436,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/React/FBReactNativeSpec"
glog:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
NotifeeCore:
:path: "../../ios"
RCT-Folly:
:podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
RCTRequired:
Expand Down Expand Up @@ -508,14 +511,15 @@ SPEC CHECKSUMS:
FirebaseInstallations: 2563cb18a723ef9c6ef18318a49519b75dce613c
FirebaseMessaging: 419b5c9d84f294a753c6501d8cfb9ced1ce37304
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 85ecdd10ee8d8ec362ef519a6a45ff9aa27b2e85
glog: 5337263514dd6f09803962437687240c5dc39aa4
GoogleDataTransport: 85fd18ff3019bb85d3f2c551d04c481dedf71fc9
GoogleUtilities: 8de2a97a17e15b6b98e38e8770e2d129a57c0040
hermes-engine: bf7577d12ac6ccf53ab8b5af3c6ccf0dd8458c5c
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96
NotifeeCore: 7163fe1ba23401a81430438a037a40a00221b80e
PromisesObjC: 68159ce6952d93e17b2dfe273b8c40907db5ba58
RCT-Folly: 803a9cfd78114b2ec0f140cfa6fa2a6bafb2d685
RCT-Folly: a21c126816d8025b547704b777a2ba552f3d9fa9
RCTRequired: e94bac8c0770aa02dd4959b86e32c6fe0e077e2d
RCTTypeSafety: 400db7e174b0cb36ba4b85aaef60789df434043e
React: 921833f22439a2cf6dbc760a56ee1bfc54aeed03
Expand All @@ -542,10 +546,10 @@ SPEC CHECKSUMS:
ReactCommon: fda8de1535cec34971adef653f9afd954142eb7c
RNFBApp: 729c0666395b1953198dc4a1ec6deb8fbe1c302e
RNFBMessaging: 8415ec196e5c1196caa26ec0742cdb48ed4d0f97
RNNotifee: f0d07c9f1829438ff3b5f80e66b405891bf54479
RNNotifeeCore: 218e4080fb14f8ddfb5d454853baac1bb46cd1d9
RNNotifee: 76848114415d00108f6139dfcdb656903ea09cab
RNNotifeeCore: 0b45d6cce948a491099d8c65f5ea04e452bc4d6f
Yoga: 63f25ad38b6f7597fa5dfee27088b29a01e83447

PODFILE CHECKSUM: 8566c3eec5afcd7bbe46173879c6fc8b9dc375ee
PODFILE CHECKSUM: 5a8c08f65af9bf9f8543478056186aaf3b8e42ef

COCOAPODS: 1.11.2
1 change: 1 addition & 0 deletions tests_react_native/ios/testing/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
<array>
<string>fetch</string>
<string>location</string>
<string>processing</string>
<string>remote-notification</string>
</array>
<key>UILaunchStoryboardName</key>
Expand Down