Skip to content

Commit 2cc2c36

Browse files
committed
Notification Foreground Listener - API update
* Rename notificationWillShowInForegroundHandler to OSNotificationLifecycleListener * It will have the `onWillDisplay` event.
1 parent eb1685a commit 2cc2c36

File tree

11 files changed

+170
-93
lines changed

11 files changed

+170
-93
lines changed

iOS_SDK/OneSignalDevApp/OneSignalDevApp/AppDelegate.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#import <UIKit/UIKit.h>
3232
#import <OneSignalFramework/OneSignalFramework.h>
3333

34-
@interface AppDelegate : UIResponder <UIApplicationDelegate, OSNotificationPermissionObserver, OSInAppMessageLifecycleListener, OSPushSubscriptionObserver>
34+
@interface AppDelegate : UIResponder <UIApplicationDelegate, OSNotificationPermissionObserver, OSInAppMessageLifecycleListener, OSPushSubscriptionObserver, OSNotificationLifecycleListener>
3535

3636
@property (strong, nonatomic) UIWindow *window;
3737

iOS_SDK/OneSignalDevApp/OneSignalDevApp/AppDelegate.m

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
6666
[alert show];
6767
#pragma clang diagnostic pop
6868
};
69-
id notificationReceiverBlock = ^(OSNotification *notif, OSNotificationDisplayResponse completion) {
70-
NSLog(@"Will Receive Notification - %@", notif.notificationId);
71-
completion(notif);
72-
};
7369

7470
// Example block for IAM action click handler
7571
id inAppMessagingActionClickBlock = ^(OSInAppMessageAction *action) {
@@ -87,7 +83,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
8783
[OneSignal.InAppMessages addLifecycleListener:self];
8884
[OneSignal.InAppMessages paused:true];
8985

90-
[OneSignal.Notifications setNotificationWillShowInForegroundHandler:notificationReceiverBlock];
86+
[OneSignal.Notifications addForegroundLifecycleListener:self];
9187
[OneSignal.Notifications setNotificationOpenedHandler:openNotificationHandler];
9288

9389
[OneSignal.User.pushSubscription addObserver:self];
@@ -134,6 +130,14 @@ - (void)handleMessageAction:(OSInAppMessageAction *)action {
134130
return;
135131
}
136132

133+
- (void)onWillDisplayNotification:(OSNotificationWillDisplayEvent *)event {
134+
NSLog(@"Dev App OSNotificationWillDisplayEvent with event: %@",event);
135+
[event preventDefault];
136+
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
137+
[event.notification display];
138+
});
139+
}
140+
137141
- (void)onWillDisplayInAppMessage:(OSInAppMessageWillDisplayEvent *)event {
138142
NSLog(@"OSInAppMessageDelegate: onWillDisplay Message: %@",event.message);
139143
return;

iOS_SDK/OneSignalDevApp/OneSignalDevAppClip/AppDelegate.m

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
5858
id openNotificationHandler = ^(OSNotificationOpenedResult *result) {
5959
NSLog(@"OSNotificationOpenedResult: %@", result.action);
6060
};
61-
id notificationReceiverBlock = ^(OSNotification *notif, OSNotificationDisplayResponse completion) {
62-
NSLog(@"Will Receive Notification - %@", notif.notificationId);
63-
completion(notif);
64-
};
6561

6662
// Example block for IAM action click handler
6763
id inAppMessagingActionClickBlock = ^(OSInAppMessageAction *action) {
@@ -87,7 +83,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
8783

8884
[OneSignal.InAppMessages paused:false];
8985

90-
[OneSignal.Notifications setNotificationWillShowInForegroundHandler:notificationReceiverBlock];
9186
[OneSignal.Notifications setNotificationOpenedHandler:openNotificationHandler];
9287

9388
NSLog(@"UNUserNotificationCenter.delegate: %@", UNUserNotificationCenter.currentNotificationCenter.delegate);

iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@
466466
DEF784642912FA5100A1F3A5 /* OSDialogInstanceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DEF784632912FA5100A1F3A5 /* OSDialogInstanceManager.m */; };
467467
DEF784652912FB2200A1F3A5 /* OSDialogInstanceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DEF784622912F79700A1F3A5 /* OSDialogInstanceManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
468468
DEF7846B2913176800A1F3A5 /* OneSignalNotifications.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DEF784292912DEB600A1F3A5 /* OneSignalNotifications.framework */; };
469-
DEF7847229132AA700A1F3A5 /* OSNotification+OneSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = DEF7847029132AA700A1F3A5 /* OSNotification+OneSignal.h */; };
469+
DEF7847229132AA700A1F3A5 /* OSNotification+OneSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = DEF7847029132AA700A1F3A5 /* OSNotification+OneSignal.h */; settings = {ATTRIBUTES = (Public, ); }; };
470470
DEF7847329132AA700A1F3A5 /* OSNotification+OneSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = DEF7847129132AA700A1F3A5 /* OSNotification+OneSignal.m */; };
471471
DEF784792914667A00A1F3A5 /* NSDateFormatter+OneSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = DE9877292591654600DE07D5 /* NSDateFormatter+OneSignal.h */; settings = {ATTRIBUTES = (Public, ); }; };
472472
DEF7847D29146B2700A1F3A5 /* OneSignalWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = DEF7847B29146B2700A1F3A5 /* OneSignalWebView.m */; };

iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification+Internal.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@
3131
#define OSNotification_Internal_h
3232

3333
@interface OSNotification(Internal)
34-
+(instancetype _Nonnull )parseWithApns:(nonnull NSDictionary *)message;
35-
- (void)setCompletionBlock:(OSNotificationDisplayResponse _Nonnull)completion;
36-
- (void)startTimeoutTimer;
37-
- (void)complete:(nullable OSNotification *)notification;
3834
@end
3935

4036
#endif /* OSNotification_Internal_h */

iOS_SDK/OneSignalSDK/OneSignalCore/Source/OSNotification.m

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,12 @@
2626
*/
2727

2828
#import <Foundation/Foundation.h>
29-
3029
#import <UIKit/UIKit.h>
31-
3230
#import "OSNotification+Internal.h"
33-
3431
#import "OSNotification.h"
35-
36-
#import "OneSignalCommonDefines.h"
37-
38-
#import "OneSignalUserDefaults.h"
39-
4032
#import "OneSignalLog.h"
4133

4234
@implementation OSNotification
43-
44-
OSNotificationDisplayResponse _completion;
45-
NSTimer *_timeoutTimer;
4635

4736
+ (instancetype)parseWithApns:(nonnull NSDictionary*)message {
4837
if (!message)
@@ -63,8 +52,6 @@ - (void)initWithRawMessage:(NSDictionary*)message {
6352
[self parseOriginalPayload];
6453

6554
[self parseOtherApnsFields];
66-
67-
_timeoutTimer = [NSTimer timerWithTimeInterval:CUSTOM_DISPLAY_TYPE_TIMEOUT target:self selector:@selector(timeoutTimerFired:) userInfo:_notificationId repeats:false];
6855
}
6956

7057
// Original OneSignal payload format.
@@ -300,34 +287,4 @@ - (NSString *)stringify {
300287
return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
301288
}
302289

303-
#pragma mark willShowInForegroundHandler Methods
304-
305-
- (void)setCompletionBlock:(OSNotificationDisplayResponse)completion {
306-
_completion = completion;
307-
}
308-
309-
- (void)complete:(OSNotification *)notification {
310-
[_timeoutTimer invalidate];
311-
if (_completion) {
312-
_completion(notification);
313-
_completion = nil;
314-
}
315-
}
316-
317-
- (void)startTimeoutTimer {
318-
[[NSRunLoop currentRunLoop] addTimer:_timeoutTimer forMode:NSRunLoopCommonModes];
319-
}
320-
321-
- (void)timeoutTimerFired:(NSTimer *)timer {
322-
[OneSignalLog onesignalLog:ONE_S_LL_ERROR
323-
message:[NSString stringWithFormat:@"Notification willShowInForeground completion timed out. Completion was not called within %f seconds.", CUSTOM_DISPLAY_TYPE_TIMEOUT]];
324-
[self complete:self];
325-
}
326-
327-
- (void)dealloc {
328-
if (_timeoutTimer && _completion) {
329-
[_timeoutTimer invalidate];
330-
}
331-
}
332-
333290
@end

iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotification+OneSignal.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@
2727

2828

2929
#import <Foundation/Foundation.h>
30-
#import <OneSignalCore/OneSignalCore.h>
30+
#import <OneSignalCore/OSNotification.h>
3131

32-
@interface OSNotification (OneSignal)
33-
- (OSNotificationDisplayResponse _Nullable)getCompletionBlock;
32+
/**
33+
Public interface used in the OSNotificationLifecycleListener's onWillDisplay event.
34+
*/
35+
@interface OSDisplayableNotification : OSNotification
36+
- (void)display;
3437
@end

iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotification+OneSignal.m

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,82 @@
2525
* THE SOFTWARE.
2626
*/
2727

28-
2928
#import "OSNotification+OneSignal.h"
29+
#import <OneSignalCore/OneSignalCore.h>
3030
#import <UIKit/UIKit.h>
31-
@implementation OSNotification (OneSignal)
32-
- (OSNotificationDisplayResponse)getCompletionBlock {
33-
OSNotificationDisplayResponse block = ^(OSNotification *notification){
34-
/*
35-
If notification is null here then display was cancelled and we need to
36-
reset the badge count to the value prior to receipt of this notif
37-
*/
38-
if (!notification) {
39-
NSInteger previousBadgeCount = [UIApplication sharedApplication].applicationIconBadgeNumber;
40-
[OneSignalUserDefaults.initShared saveIntegerForKey:ONESIGNAL_BADGE_KEY withValue:previousBadgeCount];
41-
}
42-
[self complete:notification];
43-
};
44-
return block;
45-
}
31+
32+
@interface OSNotification ()
33+
- (void)initWithRawMessage:(NSDictionary*)message;
34+
@end
35+
36+
@implementation OSDisplayableNotification
37+
38+
OSNotificationDisplayResponse _completion;
39+
NSTimer *_timeoutTimer;
40+
BOOL _wantsToDisplay = true;
41+
42+
+ (instancetype)parseWithApns:(nonnull NSDictionary*)message {
43+
if (!message)
44+
return nil;
45+
46+
OSDisplayableNotification *osNotification = [OSDisplayableNotification new];
47+
48+
[osNotification initWithRawMessage:message];
49+
[osNotification setTimeoutTimer];
50+
return osNotification;
51+
}
52+
53+
- (void)setTimeoutTimer {
54+
_timeoutTimer = [NSTimer timerWithTimeInterval:CUSTOM_DISPLAY_TYPE_TIMEOUT target:self selector:@selector(timeoutTimerFired:) userInfo:self.notificationId repeats:false];
55+
}
56+
57+
- (void)startTimeoutTimer {
58+
[[NSRunLoop currentRunLoop] addTimer:_timeoutTimer forMode:NSRunLoopCommonModes];
59+
}
60+
61+
- (void)setCompletionBlock:(OSNotificationDisplayResponse)completion {
62+
_completion = completion;
63+
}
64+
65+
- (void)display {
66+
if (!_completion) {
67+
[OneSignalLog onesignalLog:ONE_S_LL_ERROR message:@"OSNotificationWillDisplayEvent.notification.display cannot be called due to timing out or notification was already displayed."];
68+
}
69+
[self complete:self];
70+
}
71+
72+
- (void)complete:(OSDisplayableNotification *)notification {
73+
[_timeoutTimer invalidate];
74+
/*
75+
If notification is null here then display was cancelled and we need to
76+
reset the badge count to the value prior to receipt of this notif
77+
*/
78+
if (!notification) {
79+
NSInteger previousBadgeCount = [UIApplication sharedApplication].applicationIconBadgeNumber;
80+
[OneSignalUserDefaults.initShared saveIntegerForKey:ONESIGNAL_BADGE_KEY withValue:previousBadgeCount];
81+
}
82+
if (_completion) {
83+
_completion(notification);
84+
_completion = nil;
85+
}
86+
}
87+
88+
- (void)setWantsToDisplay:(BOOL)display {
89+
_wantsToDisplay = display;
90+
}
91+
92+
- (void)timeoutTimerFired:(NSTimer *)timer {
93+
[OneSignalLog onesignalLog:ONE_S_LL_WARN message:[NSString stringWithFormat:@"OSNotificationLifecycleListener:onWillDisplayNotification timed out. Display was not called within %f seconds. Continue with display notification: %d", CUSTOM_DISPLAY_TYPE_TIMEOUT, _wantsToDisplay]];
94+
if (_wantsToDisplay) {
95+
[self complete:self];
96+
} else {
97+
[self complete:nil];
98+
}
99+
}
100+
101+
- (void)dealloc {
102+
if (_timeoutTimer && _completion) {
103+
[_timeoutTimer invalidate];
104+
}
105+
}
46106
@end

iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotificationsManager.h

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,31 @@
3030
#import <OneSignalNotifications/OSPermission.h>
3131
#import <OneSignalCore/OneSignalCore.h>
3232
#import <UIKit/UIKit.h>
33+
#import <OneSignalNotifications/OSNotification+OneSignal.h>
3334

34-
// If the completion block is not called within 25 seconds of this block being called in notificationWillShowInForegroundHandler then the completion will be automatically fired.
35-
typedef void (^OSNotificationWillShowInForegroundBlock)(OSNotification * _Nonnull notification, OSNotificationDisplayResponse _Nonnull completion);
3635
typedef void (^OSNotificationOpenedBlock)(OSNotificationOpenedResult * _Nonnull result);
3736

37+
@interface OSNotificationWillDisplayEvent : NSObject
38+
39+
@property (readonly, strong, nonatomic, nonnull) OSDisplayableNotification *notification; // TODO: strong? nonatomic? nullable?
40+
- (void)preventDefault;
41+
42+
@end
43+
44+
@protocol OSNotificationLifecycleListener <NSObject>
45+
- (void)onWillDisplayNotification:(OSNotificationWillDisplayEvent *_Nonnull)event NS_SWIFT_NAME(onWillDisplay(event:));
46+
@end
47+
3848
/**
3949
Public API for the Notifications namespace.
4050
*/
4151
@protocol OSNotifications <NSObject>
4252
+ (BOOL)permission NS_REFINED_FOR_SWIFT;
4353
+ (BOOL)canRequestPermission NS_REFINED_FOR_SWIFT;
4454
+ (OSNotificationPermission)permissionNative NS_REFINED_FOR_SWIFT;
45-
+ (void)setNotificationWillShowInForegroundHandler:(OSNotificationWillShowInForegroundBlock _Nullable)block;
55+
+ (void)addForegroundLifecycleListener:(NSObject<OSNotificationLifecycleListener> *_Nullable)listener;
56+
+ (void)removeForegroundLifecycleListener:(NSObject<OSNotificationLifecycleListener> *_Nullable)listener;
57+
4658
+ (void)setNotificationOpenedHandler:(OSNotificationOpenedBlock _Nullable)block;
4759
+ (void)requestPermission:(OSUserResponseBlock _Nullable )block;
4860
+ (void)requestPermission:(OSUserResponseBlock _Nullable )block fallbackToSettings:(BOOL)fallback;
@@ -65,6 +77,7 @@ typedef void (^OSNotificationOpenedBlock)(OSNotificationOpenedResult * _Nonnull
6577
@interface OSNotificationsManager : NSObject <OSNotifications>
6678

6779
@property (class, weak, nonatomic, nullable) id<OneSignalNotificationsDelegate> delegate;
80+
@property (class, weak, nonatomic, nullable) NSObject<OSNotificationLifecycleListener> *lifecycleListener;
6881

6982
+ (Class<OSNotifications> _Nonnull)Notifications;
7083
+ (void)start;
@@ -97,7 +110,7 @@ typedef void (^OSNotificationOpenedBlock)(OSNotificationOpenedResult * _Nonnull
97110
// This is set by the user module
98111
+ (void)setPushSubscriptionId:(NSString *_Nullable)pushSubscriptionId;
99112

100-
+ (void)handleWillShowInForegroundHandlerForNotification:(OSNotification *_Nonnull)notification completion:(OSNotificationDisplayResponse _Nonnull)completion;
113+
+ (void)handleWillShowInForegroundForNotification:(OSNotification *_Nonnull)notification completion:(OSNotificationDisplayResponse _Nonnull)completion;
101114
+ (void)handleNotificationAction:(OSNotificationActionType)actionType actionID:(NSString* _Nonnull)actionID;
102115

103116
+ (BOOL)clearBadgeCount:(BOOL)fromNotifOpened;

0 commit comments

Comments
 (0)