Skip to content

Commit

Permalink
Merge pull request #1262 from OneSignal/5.0.0/notification_click_list…
Browse files Browse the repository at this point in the history
…ener_api

[5.0.0] Notification Click Listener - API update
  • Loading branch information
emawby authored and nan-li committed Oct 30, 2023
2 parents 4598d7b + 961e1fc commit 9d4e330
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 78 deletions.
2 changes: 1 addition & 1 deletion iOS_SDK/OneSignalDevApp/OneSignalDevApp/AppDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#import <UIKit/UIKit.h>
#import <OneSignalFramework/OneSignalFramework.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, OSNotificationPermissionObserver, OSInAppMessageLifecycleListener, OSPushSubscriptionObserver, OSNotificationLifecycleListener, OSInAppMessageClickListener>
@interface AppDelegate : UIResponder <UIApplicationDelegate, OSNotificationPermissionObserver, OSInAppMessageLifecycleListener, OSPushSubscriptionObserver, OSNotificationLifecycleListener, OSInAppMessageClickListener, OSNotificationClickListener>

@property (strong, nonatomic) UIWindow *window;

Expand Down
17 changes: 5 additions & 12 deletions iOS_SDK/OneSignalDevApp/OneSignalDevApp/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(

_notificationDelegate = [OneSignalNotificationCenterDelegate new];

id openNotificationHandler = ^(OSNotificationOpenedResult *result) {
// TODO: opened handler Not triggered
NSLog(@"OSNotificationOpenedResult: %@", result.action);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated"
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Notifiation Opened In App Delegate" message:@"Notification Opened In App Delegate" delegate:self cancelButtonTitle:@"Delete" otherButtonTitles:@"Cancel", nil];
[alert show];
#pragma clang diagnostic pop
};

// OneSignal Init with app id and lauch options
[OneSignal setLaunchURLsInApp:YES];
[OneSignal setProvidesNotificationSettingsView:NO];
Expand All @@ -75,8 +65,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
[OneSignal.InAppMessages paused:true];

[OneSignal.Notifications addForegroundLifecycleListener:self];
[OneSignal.Notifications setNotificationOpenedHandler:openNotificationHandler];

[OneSignal.Notifications addClickListener:self];
[OneSignal.User.pushSubscription addObserver:self];
NSLog(@"OneSignal Demo App push subscription observer added");

Expand Down Expand Up @@ -115,6 +104,10 @@ - (void)onPushSubscriptionDidChangeWithState:(OSPushSubscriptionChangedState *)s
mainController.subscriptionSegmentedControl.selectedSegmentIndex = (NSInteger) state.current.optedIn;
}

- (void)onClickNotification:(OSNotificationClickEvent * _Nonnull)event {
NSLog(@"Dev App onClickNotification with event %@", [event jsonRepresentation]);
}

#pragma mark OSInAppMessageDelegate

- (void)onClickInAppMessage:(OSInAppMessageClickEvent * _Nonnull)event {
Expand Down
6 changes: 0 additions & 6 deletions iOS_SDK/OneSignalDevApp/OneSignalDevAppClip/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
[OneSignal.Debug setLogLevel:ONE_S_LL_VERBOSE];
[OneSignal.Debug setAlertLevel:ONE_S_LL_NONE];
_notificationDelegate = [OneSignalNotificationCenterDelegate new];

id openNotificationHandler = ^(OSNotificationOpenedResult *result) {
NSLog(@"OSNotificationOpenedResult: %@", result.action);
};

// OneSignal Init with app id and lauch options
[OneSignal setLaunchURLsInApp:YES];
Expand All @@ -74,8 +70,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(

[OneSignal.InAppMessages paused:false];

[OneSignal.Notifications setNotificationOpenedHandler:openNotificationHandler];

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

return YES;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,17 @@ typedef NS_ENUM(NSUInteger, OSNotificationActionType) {
OSNotificationActionTypeActionTaken
};

@interface OSNotificationAction : NSObject

/* The type of the notification action */
@property(readonly)OSNotificationActionType type;

@interface OSNotificationClickResult : NSObject
/* The ID associated with the button tapped. NULL when the actionType is NotificationTapped */
@property(readonly, nullable)NSString* actionId;
@property(readonly, nullable)NSString* url;

@end

@interface OSNotificationOpenedResult : NSObject
@interface OSNotificationClickEvent : NSObject

@property(readonly, nonnull)OSNotification* notification;
@property(readonly, nonnull)OSNotificationAction *action;
@property(readonly, nonnull)OSNotificationClickResult *result;

/* Convert object into an NSString that can be convertible into a custom Dictionary / JSON Object */
- (NSString* _Nonnull)stringify;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
+(void)init;
+(void)updateFromDownloadParams:(NSDictionary*)params;

+(void)trackOpenEvent:(OSNotificationOpenedResult*)results;
+(void)trackOpenEvent:(OSNotificationClickEvent*)event;
+(void)trackReceivedEvent:(OSNotification*)notification;
+(void)trackInfluenceOpenEvent;
@end
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ + (NSString*)getCampaignNameFromNotification:(OSNotification *)notification {
return [notification.title substringToIndex:titleLength];
}

+ (void)trackOpenEvent:(OSNotificationOpenedResult*)results {
+ (void)trackOpenEvent:(OSNotificationClickEvent*)event {
if (!trackingEnabled)
return;

Expand All @@ -97,8 +97,8 @@ + (void)trackOpenEvent:(OSNotificationOpenedResult*)results {
parameters:@{
@"source": @"OneSignal",
@"medium": @"notification",
@"notification_id": results.notification.notificationId,
@"campaign": [self getCampaignNameFromNotification:results.notification]
@"notification_id": event.notification.notificationId,
@"campaign": [self getCampaignNameFromNotification:event.notification]
}];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
#import <UIKit/UIKit.h>
#import <OneSignalNotifications/OSNotification+OneSignal.h>

typedef void (^OSNotificationOpenedBlock)(OSNotificationOpenedResult * _Nonnull result);
@protocol OSNotificationClickListener <NSObject>
- (void)onClickNotification:(OSNotificationClickEvent *_Nonnull)event
NS_SWIFT_NAME(onClick(event:));
@end

@interface OSNotificationWillDisplayEvent : NSObject

Expand All @@ -54,8 +57,8 @@ typedef void (^OSNotificationOpenedBlock)(OSNotificationOpenedResult * _Nonnull
+ (OSNotificationPermission)permissionNative NS_REFINED_FOR_SWIFT;
+ (void)addForegroundLifecycleListener:(NSObject<OSNotificationLifecycleListener> *_Nullable)listener;
+ (void)removeForegroundLifecycleListener:(NSObject<OSNotificationLifecycleListener> *_Nullable)listener;

+ (void)setNotificationOpenedHandler:(OSNotificationOpenedBlock _Nullable)block;
+ (void)addClickListener:(NSObject<OSNotificationClickListener>*_Nonnull)listener NS_REFINED_FOR_SWIFT;
+ (void)removeClickListener:(NSObject<OSNotificationClickListener>*_Nonnull)listener NS_REFINED_FOR_SWIFT;
+ (void)requestPermission:(OSUserResponseBlock _Nullable )block;
+ (void)requestPermission:(OSUserResponseBlock _Nullable )block fallbackToSettings:(BOOL)fallback;
+ (void)registerForProvisionalAuthorization:(OSUserResponseBlock _Nullable )block NS_REFINED_FOR_SWIFT;
Expand Down Expand Up @@ -111,8 +114,7 @@ typedef void (^OSNotificationOpenedBlock)(OSNotificationOpenedResult * _Nonnull
+ (void)setPushSubscriptionId:(NSString *_Nullable)pushSubscriptionId;

+ (void)handleWillShowInForegroundForNotification:(OSNotification *_Nonnull)notification completion:(OSNotificationDisplayResponse _Nonnull)completion;
+ (void)handleNotificationAction:(OSNotificationActionType)actionType actionID:(NSString* _Nonnull)actionID;

+ (void)handleNotificationActionWithUrl:(NSString* _Nullable)url actionID:(NSString* _Nonnull)actionID;
+ (BOOL)clearBadgeCount:(BOOL)fromNotifOpened;

+ (BOOL)receiveRemoteNotification:(UIApplication* _Nonnull)application UserInfo:(NSDictionary* _Nonnull)userInfo completionHandler:(void (^_Nonnull)(UIBackgroundFetchResult))completionHandler;
Expand Down
102 changes: 59 additions & 43 deletions iOS_SDK/OneSignalSDK/OneSignalNotifications/OSNotificationsManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ of this software and associated documentation files (the "Software"), to deal
#import "UNUserNotificationCenter+OneSignalNotifications.h"
#import "UIApplicationDelegate+OneSignalNotifications.h"

@implementation OSNotificationOpenedResult
@synthesize notification = _notification, action = _action;
@implementation OSNotificationClickEvent
@synthesize notification = _notification, result = _result;

- (id)initWithNotification:(OSNotification*)notification action:(OSNotificationAction*)action {
- (id)initWithNotification:(OSNotification*)notification result:(OSNotificationClickResult*)result {
self = [super init];
if(self) {
_notification = notification;
_action = action;
_result = result;
}
return self;
}
Expand All @@ -63,25 +63,24 @@ - (NSDictionary *_Nonnull)jsonRepresentation {
error:&jsonError];

NSMutableDictionary* obj = [NSMutableDictionary new];
NSMutableDictionary* action = [NSMutableDictionary new];
[action setObject:self.action.actionId forKeyedSubscript:@"actionID"];
[obj setObject:action forKeyedSubscript:@"action"];
NSMutableDictionary* result = [NSMutableDictionary new];
[result setObject:self.result.actionId forKeyedSubscript:@"actionID"];
[result setObject:self.result.url forKeyedSubscript:@"url"];
[obj setObject:result forKeyedSubscript:@"result"];
[obj setObject:notifDict forKeyedSubscript:@"notification"];
if(self.action.type)
[obj[@"action"] setObject:@(self.action.type) forKeyedSubscript: @"type"];


return obj;
}

@end

@implementation OSNotificationAction
@synthesize type = _type, actionId = _actionId;
@implementation OSNotificationClickResult
@synthesize url = _url, actionId = _actionId;

-(id)initWithActionType:(OSNotificationActionType)type :(NSString*)actionID {
-(id)initWithUrl:(NSString*)url :(NSString*)actionID {
self = [super init];
if(self) {
_type = type;
_url = url;
_actionId = actionID;
}
return self;
Expand Down Expand Up @@ -149,8 +148,14 @@ + (void)setLifecycleListener:(id<OSNotificationLifecycleListener>)lifecycleListe

static int mSubscriptionStatus = -1;

static NSMutableArray<OSNotificationOpenedResult*> *_unprocessedOpenedNotifis;
static OSNotificationOpenedBlock _notificationOpenedHandler;
static NSMutableArray<OSNotificationClickEvent*> *_unprocessedClickEvents;
static NSMutableArray<NSObject<OSNotificationClickListener> *> *_clickListeners;
+ (NSMutableArray<NSObject<OSNotificationClickListener> *>*)clickListeners {
if (!_clickListeners)
_clickListeners = [NSMutableArray new];
return _clickListeners;
}

static NSDictionary* _lastMessageReceived;
static NSString *_lastMessageID = @"";
static NSString *_lastMessageIdFromAction;
Expand Down Expand Up @@ -255,7 +260,7 @@ + (void)resetLocals {
_lastMessageReceived = nil;
_lastMessageIdFromAction = nil;
_lastMessageID = @"";
_unprocessedOpenedNotifis = nil;
_unprocessedClickEvents = nil;
}

+ (void)setLastPermissionState:(OSPermissionStateInternal *)lastPermissionState {
Expand Down Expand Up @@ -693,7 +698,7 @@ + (void)handleNotificationOpened:(NSDictionary*)messageDict
// [[OSSessionManager sharedSessionManager] onDirectInfluenceFromNotificationOpen:_appEntryState withNotificationId:messageId];
// }

[self handleNotificationAction:actionType actionID:actionID];
[self handleNotificationActionWithUrl:notification.launchURL actionID:actionID];
}

+ (void)submitNotificationOpened:(NSString*)messageId {
Expand Down Expand Up @@ -793,28 +798,35 @@ + (BOOL)handleIAMPreview:(OSNotification *)notification {
return NO;
}

+ (void)handleNotificationAction:(OSNotificationActionType)actionType actionID:(NSString*)actionID {
+ (void)handleNotificationActionWithUrl:(NSString*)url actionID:(NSString*)actionID {
if (![OneSignalCoreHelper isOneSignalPayload:_lastMessageReceived])
return;

OSNotificationAction *action = [[OSNotificationAction alloc] initWithActionType:actionType :actionID];
OSNotificationClickResult *result = [[OSNotificationClickResult alloc] initWithUrl:url :actionID];
OSNotification *notification = [OSNotification parseWithApns:_lastMessageReceived];
OSNotificationOpenedResult *result = [[OSNotificationOpenedResult alloc] initWithNotification:notification action:action];
OSNotificationClickEvent *event = [[OSNotificationClickEvent alloc] initWithNotification:notification result:result];

// Prevent duplicate calls to same action
if ([notification.notificationId isEqualToString:_lastMessageIdFromAction])
return;
_lastMessageIdFromAction = notification.notificationId;

[OneSignalTrackFirebaseAnalytics trackOpenEvent:result];
if (!_notificationOpenedHandler) {
[self addUnprocessedOpenedNotifi:result];
[OneSignalTrackFirebaseAnalytics trackOpenEvent:event];

if (self.clickListeners.count == 0) {
[self addUnprocessedClickEvent:event];
return;
}
_notificationOpenedHandler(result);
[self fireClickListenersForEvent:event];
}

+ (void)fireClickListenersForEvent:(OSNotificationClickEvent*)event {
for (NSObject<OSNotificationClickListener> *listener in self.clickListeners) {
if ([listener respondsToSelector:@selector(onClickNotification:)]) {
[listener onClickNotification:event];
}
}
}

+ (void)lastMessageReceived:(NSDictionary*)message {
_lastMessageReceived = message;
Expand All @@ -828,11 +840,15 @@ + (BOOL)shouldSuppressURL {
return shouldSuppress ?: false;
}

+ (void)setNotificationOpenedHandler:(OSNotificationOpenedBlock)block {
_notificationOpenedHandler = block;
[OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:@"Notification opened handler set successfully"];
[self fireNotificationOpenedHandlerForUnprocessedEvents];

+ (void)addClickListener:(NSObject<OSNotificationClickListener>*)listener {
[self.clickListeners addObject:listener];
[OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:@"Notification click listener added successfully"];
[self fireClickListenersForUnprocessedEvents];
}

+ (void)removeClickListener:(NSObject<OSNotificationClickListener>*)listener {
[self.clickListeners removeObject:listener];
[OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:@"Notification click listener removed successfully"];
}

+ (void)addForegroundLifecycleListener:(NSObject<OSNotificationLifecycleListener> *_Nullable)listener {
Expand All @@ -845,24 +861,24 @@ + (void)removeForegroundLifecycleListener:(NSObject<OSNotificationLifecycleListe
[OneSignalLog onesignalLog:ONE_S_LL_VERBOSE message:@"ForegroundLifecycleListener removed successfully"];
}

+ (NSMutableArray<OSNotificationOpenedResult*>*)getUnprocessedOpenedNotifis {
if (!_unprocessedOpenedNotifis)
_unprocessedOpenedNotifis = [NSMutableArray new];
return _unprocessedOpenedNotifis;
+ (NSMutableArray<OSNotificationClickEvent*>*)getUnprocessedClickEvents {
if (!_unprocessedClickEvents)
_unprocessedClickEvents = [NSMutableArray new];
return _unprocessedClickEvents;
}

+ (void)addUnprocessedOpenedNotifi:(OSNotificationOpenedResult*)result {
[[self getUnprocessedOpenedNotifis] addObject:result];
+ (void)addUnprocessedClickEvent:(OSNotificationClickEvent*)event {
[[self getUnprocessedClickEvents] addObject:event];
}

+ (void)fireNotificationOpenedHandlerForUnprocessedEvents {
if (!_notificationOpenedHandler)
+ (void)fireClickListenersForUnprocessedEvents {
if (self.clickListeners.count == 0) {
return;

for (OSNotificationOpenedResult* notification in [self getUnprocessedOpenedNotifis]) {
_notificationOpenedHandler(notification);
}
_unprocessedOpenedNotifis = [NSMutableArray new];
for (OSNotificationClickEvent* event in [self getUnprocessedClickEvents]) {
[self fireClickListenersForEvent:event];
}
_unprocessedClickEvents = [NSMutableArray new];
}

+ (BOOL)receiveRemoteNotification:(UIApplication*)application UserInfo:(NSDictionary*)userInfo completionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
Expand Down
8 changes: 8 additions & 0 deletions iOS_SDK/OneSignalSDK/Source/OneSignalSwiftInterface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@ public extension OSNotifications {
static func removePermissionObserver(_ observer: OSNotificationPermissionObserver) {
return __remove(observer)
}

static func addClickListener(_ listener: OSNotificationClickListener) {
return __add(listener)
}

static func removeClickListener(_ listener: OSNotificationClickListener) {
return __remove(listener)
}
}

public extension OSLocation {
Expand Down

0 comments on commit 9d4e330

Please sign in to comment.