From 1205d2c38f393650136de5f89f6f29a221f70e87 Mon Sep 17 00:00:00 2001 From: Jenna Antilla <46546946+jennantilla@users.noreply.github.com> Date: Thu, 4 Jan 2024 17:00:44 -0800 Subject: [PATCH 01/11] Update User namespace - add getters for onesignal ID/external ID - add user state observer --- www/UserNamespace.ts | 69 ++++++++++++++++++++++++++++++++++++++++++++ www/index.ts | 5 ++++ 2 files changed, 74 insertions(+) diff --git a/www/UserNamespace.ts b/www/UserNamespace.ts index 53517f84..761bf9f4 100644 --- a/www/UserNamespace.ts +++ b/www/UserNamespace.ts @@ -3,10 +3,28 @@ import PushSubscription from "./PushSubscriptionNamespace"; // Suppress TS warnings about window.cordova declare let window: any; // turn off type checking +// Represents the current user state +export interface UserState { + onesignalId ?: string; + externalId ?: string; +} + +export interface UserChangedState { + current: UserState; +} + export default class User { // The push subscription associated to the current user. pushSubscription: PushSubscription = new PushSubscription(); + private _userStateObserverList: ((event:UserChangedState)=>void)[] = []; + + private _processFunctionList(array: ((event:UserChangedState)=>void)[], param: UserChangedState): void { + for (let i = 0; i < array.length; i++) { + array[i](param); + } + } + /** * Explicitly set a 2-character language code for the user. * @param {string} language @@ -159,4 +177,55 @@ export default class User { window.cordova.exec(resolve, reject, "OneSignalPush", "getTags", []); }); }; + + /** + * Add a callback that fires when the OneSignal User state changes. + * @param {(event: UserChangedState)=>void} listener + * @returns void + */ + addEventListener(event: "change", listener: (event: UserChangedState) => void) { + this._userStateObserverList.push(listener as (event: UserChangedState) => void); + const userCallBackProcessor = (state: UserChangedState) => { + this._processFunctionList(this._userStateObserverList, state); + }; + window.cordova.exec(userCallBackProcessor, function(){}, "OneSignalPush", "addUserStateObserver", []); + } + + /** + * Remove a User State observer that has been previously added. + * @param {(event: UserChangedState)=>void} listener + * @returns void + */ + removeEventListener(event: "change", listener: (event: UserChangedState) => void) { + let index = this._userStateObserverList.indexOf(listener); + if (index !== -1) { + this._userStateObserverList.splice(index, 1); + } + } + + /** + * Get the nullable OneSignal Id associated with the current user. + * @returns {Promise} + */ + getOnesignalId(): Promise { + return new Promise((resolve, reject) => { + const callback = (response: {value: string}) => { + resolve(response.value ? response.value : null) + }; + window.cordova.exec(callback, reject, "OneSignalPush", "getOnesignalId", []); + }); + } + + /** + * Get the nullable External Id associated with the current user. + * @returns {Promise} + */ + getExternalId(): Promise { + return new Promise((resolve, reject) => { + const callback = (response: {value: string}) => { + resolve(response.value ? response.value : null) + }; + window.cordova.exec(callback, reject, "OneSignalPush", "getExternalId", []); + }); + } } diff --git a/www/index.ts b/www/index.ts index 9ca7e259..04a9f2c1 100644 --- a/www/index.ts +++ b/www/index.ts @@ -140,4 +140,9 @@ export { InAppMessageActionUrlType, } from "./models/InAppMessage"; +export { + UserState, + UserChangedState, +} from "./UserNamespace"; + export default OneSignal; From 0a5b5cec4a726163fd2d6826c80593c657b5a7d2 Mon Sep 17 00:00:00 2001 From: Jenna Antilla <46546946+jennantilla@users.noreply.github.com> Date: Thu, 4 Jan 2024 15:11:05 -0800 Subject: [PATCH 02/11] [Android] Add getters for onesignal ID/external ID, add user state observer --- .../cordova/OneSignalController.java | 28 +++++++++++ .../cordova/OneSignalObserverController.java | 48 +++++++++++++++++++ .../com/onesignal/cordova/OneSignalPush.java | 16 +++++++ 3 files changed, 92 insertions(+) diff --git a/src/android/com/onesignal/cordova/OneSignalController.java b/src/android/com/onesignal/cordova/OneSignalController.java index d280e294..9655b3d2 100644 --- a/src/android/com/onesignal/cordova/OneSignalController.java +++ b/src/android/com/onesignal/cordova/OneSignalController.java @@ -199,6 +199,34 @@ public static boolean getTags(CallbackContext callbackContext) { return true; } + public static boolean getOnesignalId(CallbackContext callbackContext) { + String onesignalId = OneSignal.getUser().getOnesignalId(); + try { + JSONObject onesignalIdObject = new JSONObject (); + if (!onesignalId.isEmpty()) { + onesignalIdObject.put("value", onesignalId); + } + CallbackHelper.callbackSuccess(callbackContext, onesignalIdObject); + } catch (JSONException e){ + e.printStackTrace(); + } + return true; + } + + public static boolean getExternalId(CallbackContext callbackContext) { + String externalId = OneSignal.getUser().getExternalId(); + try { + JSONObject externalIdObject = new JSONObject (); + if (!externalId.isEmpty()) { + externalIdObject.put("value", externalId); + } + CallbackHelper.callbackSuccess(callbackContext, externalIdObject); + } catch (JSONException e){ + e.printStackTrace(); + } + return true; + } + /** * Notifications */ diff --git a/src/android/com/onesignal/cordova/OneSignalObserverController.java b/src/android/com/onesignal/cordova/OneSignalObserverController.java index df186881..59b9108a 100644 --- a/src/android/com/onesignal/cordova/OneSignalObserverController.java +++ b/src/android/com/onesignal/cordova/OneSignalObserverController.java @@ -14,13 +14,18 @@ import com.onesignal.user.subscriptions.PushSubscriptionChangedState; import com.onesignal.user.subscriptions.PushSubscriptionState; import com.onesignal.notifications.IPermissionObserver; +import com.onesignal.user.state.UserState; +import com.onesignal.user.state.UserChangedState; +import com.onesignal.user.state.IUserStateObserver; public class OneSignalObserverController { private static CallbackContext jsPermissionObserverCallBack; private static CallbackContext jsSubscriptionObserverCallBack; + private static CallbackContext jsUserObserverCallBack; private static IPermissionObserver permissionObserver; private static IPushSubscriptionObserver pushSubscriptionObserver; + private static IUserStateObserver userStateObserver; public static boolean addPermissionObserver(CallbackContext callbackContext) { jsPermissionObserverCallBack = callbackContext; @@ -65,6 +70,49 @@ public void onPushSubscriptionChange(PushSubscriptionChangedState state) { return true; } + public static boolean addUserStateObserver(CallbackContext callbackContext) { + jsUserObserverCallBack = callbackContext; + if (userStateObserver == null) { + userStateObserver = new IUserStateObserver() { + @Override + public void onUserStateChange(UserChangedState state) { + UserState user = state.getCurrent(); + + if (!(user instanceof UserState)) { + return; + } + + try { + JSONObject hash = new JSONObject(); + hash.put("current", createUserIds(state.getCurrent())); + + CallbackHelper.callbackSuccess(jsUserObserverCallBack, hash); + + } catch (Exception e) { + e.printStackTrace(); + } + } + }; + OneSignal.getUser().addObserver(userStateObserver); + } + return true; + } + + private static JSONObject createUserIds(UserState user) { + JSONObject userIds = new JSONObject(); + try { + if (!user.getExternalId().isEmpty()) { + userIds.put("externalId", user.getExternalId()); + } + if (!user.getOnesignalId().isEmpty()) { + userIds.put("onesignalId", user.getOnesignalId()); + } + } catch (JSONException e) { + e.printStackTrace(); + } + return userIds; + } + private static JSONObject createPushSubscriptionProperties(PushSubscriptionState pushSubscription) { JSONObject pushSubscriptionProperties = new JSONObject(); try { diff --git a/src/android/com/onesignal/cordova/OneSignalPush.java b/src/android/com/onesignal/cordova/OneSignalPush.java index 7dda5ed4..466d7a6d 100644 --- a/src/android/com/onesignal/cordova/OneSignalPush.java +++ b/src/android/com/onesignal/cordova/OneSignalPush.java @@ -82,6 +82,10 @@ public class OneSignalPush extends CordovaPlugin implements INotificationLifecyc private static final String ADD_PERMISSION_OBSERVER = "addPermissionObserver"; private static final String ADD_PUSH_SUBSCRIPTION_OBSERVER = "addPushSubscriptionObserver"; + private static final String ADD_USER_STATE_OBSERVER = "addUserStateObserver"; + + private static final String GET_ONESIGNAL_ID = "getOnesignalId"; + private static final String GET_EXTERNAL_ID = "getExternalId"; private static final String OPT_IN = "optInPushSubscription"; private static final String OPT_OUT = "optOutPushSubscription"; @@ -432,6 +436,18 @@ public boolean execute(String action, JSONArray data, CallbackContext callbackCo result = OneSignalObserverController.addPushSubscriptionObserver(callbackContext); break; + case ADD_USER_STATE_OBSERVER: + result = OneSignalObserverController.addUserStateObserver(callbackContext); + break; + + case GET_ONESIGNAL_ID: + result = OneSignalController.getOnesignalId(callbackContext); + break; + + case GET_EXTERNAL_ID: + result = OneSignalController.getExternalId(callbackContext); + break; + case OPT_IN: result = OneSignalController.optInPushSubscription(); break; From dd79f82f6988c306efbc915194a7af90c2ba9a9a Mon Sep 17 00:00:00 2001 From: Jenna Antilla <46546946+jennantilla@users.noreply.github.com> Date: Thu, 4 Jan 2024 17:40:15 -0800 Subject: [PATCH 03/11] Update Migration Guide include new User methods: - getOnesignalId - getExternalId - addEventListener/removeEventListener --- MIGRATION_GUIDE.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 73b71782..c6c20d9e 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -222,8 +222,21 @@ The User name space is accessible via `OneSignal.User` and provides access to us | `OneSignal.User.removeTag("KEY");` | *Remove the data tag with the provided key from the current user.* | | `OneSignal.User.removeTags(["KEY_01", "KEY_02"]);` | *Remove multiple tags with the provided keys from the current user.* | | `OneSignal.User.getTags();` | *Returns the local tags for the current user.* | +| `OneSignal.User.addEventListener("change", (event: UserChangedState) => void);`

***See below for usage*** | *Add a User State callback which contains the nullable onesignalId and externalId. The listener will be fired when these values change.* | +| `OneSignal.User.getOnesignalId();` | *Returns the nullable OneSignal ID for the current user.* | +| `OneSignal.User.getExternalId();` | *Returns the nullable external ID for the current user.* | +### User State Listener +**Cordova/Ionic** +```typescript + const listener = (event: UserChangedState) => { + console.log("User changed: " + (event)); + }; + OneSignal.User.addEventListener("change", listener); + // Remove the listener + OneSignal.User.removeEventListener("change", listener); +``` ## Push Subscription Namespace From 2f6ea2419a542131e4e6775467c37edb375cd39f Mon Sep 17 00:00:00 2001 From: Jenna Antilla <46546946+jennantilla@users.noreply.github.com> Date: Tue, 9 Jan 2024 10:26:09 -0800 Subject: [PATCH 04/11] [iOS] Add getters for onesignal ID/external ID, add user state observer --- src/ios/OneSignalPush.h | 7 +++++- src/ios/OneSignalPush.m | 47 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/ios/OneSignalPush.h b/src/ios/OneSignalPush.h index e8308b73..7782cb2e 100644 --- a/src/ios/OneSignalPush.h +++ b/src/ios/OneSignalPush.h @@ -31,7 +31,7 @@ #import -@interface OneSignalPush : CDVPlugin +@interface OneSignalPush : CDVPlugin - (void)setProvidesNotificationSettingsView:(CDVInvokedUrlCommand* _Nonnull)command; - (void)addForegroundLifecycleListener:(CDVInvokedUrlCommand* _Nonnull)command; @@ -53,6 +53,10 @@ - (void)removeTags:(CDVInvokedUrlCommand* _Nonnull)command; - (void)getTags:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)addUserStateObserver:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)getOnesignalId:(CDVInvokedUrlCommand* _Nonnull)command; +- (void)getExternalId:(CDVInvokedUrlCommand* _Nonnull)command; + // Push Subscription - (void)addPushSubscriptionObserver:(CDVInvokedUrlCommand* _Nonnull)command; - (void)getPushSubscriptionId:(CDVInvokedUrlCommand* _Nonnull)command; @@ -69,6 +73,7 @@ - (void)canRequestPermission:(CDVInvokedUrlCommand* _Nonnull)command; - (void)registerForProvisionalAuthorization:(CDVInvokedUrlCommand* _Nonnull)command; - (void)clearAllNotifications:(CDVInvokedUrlCommand* _Nonnull)command; + // Android Only - Notifications - (void)removeNotification:(CDVInvokedUrlCommand* _Nonnull)command; - (void)removeGroupedNotifications:(CDVInvokedUrlCommand* _Nonnull)command; diff --git a/src/ios/OneSignalPush.m b/src/ios/OneSignalPush.m index f3c4b80c..d9206b3a 100644 --- a/src/ios/OneSignalPush.m +++ b/src/ios/OneSignalPush.m @@ -165,6 +165,45 @@ - (void)onPushSubscriptionDidChangeWithState:(OSPushSubscriptionChangedState *)s successCallback(subscriptionObserverCallbackId, [state jsonRepresentation]); } +- (void)onUserStateDidChangeWithState:(OSUserChangedState * _Nonnull)state { + NSString *onesignalId = state.current.onesignalId; + NSString *externalId = state.current.externalId; + + NSMutableDictionary *result = [NSMutableDictionary new]; + + NSMutableDictionary *currentObject = [NSMutableDictionary new]; + if (onesignalId.length > 0) { + currentObject[@"onesignalId"] = onesignalId; + } + if (externalId.length > 0) { + currentObject[@"externalId"] = externalId; + } + + result[@"current"] = currentObject; + + successCallback(userObserverCallbackId, result); +} + +- (void)getOnesignalId:(CDVInvokedUrlCommand *)command { + NSString *onesignalId = OneSignal.User.onesignalId; + + NSDictionary *result = @{ + @"value" : (onesignalId ? onesignalId : [NSNull null]) + }; + + successCallback(command.callbackId, result); +} + +- (void)getExternalId:(CDVInvokedUrlCommand *)command { + NSString *externalId = OneSignal.User.externalId; + + NSDictionary *result = @{ + @"value" : (externalId ? externalId : [NSNull null]) + }; + + successCallback(command.callbackId, result); +} + - (void)setProvidesNotificationSettingsView:(CDVInvokedUrlCommand *)command { BOOL providesView = command.arguments[0]; [OneSignal setProvidesNotificationSettingsView:providesView]; @@ -272,6 +311,14 @@ - (void)addPushSubscriptionObserver:(CDVInvokedUrlCommand*)command { [OneSignal.User.pushSubscription addObserver:self]; } +- (void)addUserStateObserver:(CDVInvokedUrlCommand*)command { + bool first = userObserverCallbackId == nil; + userObserverCallbackId = command.callbackId; + if (first) { + [OneSignal.User addObserver:self]; + } +} + - (void)getPushSubscriptionId:(CDVInvokedUrlCommand*)command { NSString *pushId = OneSignal.User.pushSubscription.id; if (pushId) { From 561cf1f48d26a549a6f769b8eda6e90f7863a358 Mon Sep 17 00:00:00 2001 From: Jenna Antilla <46546946+jennantilla@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:38:19 -0800 Subject: [PATCH 05/11] Add await to the id getters --- MIGRATION_GUIDE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index c6c20d9e..33ae5ba6 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -223,8 +223,8 @@ The User name space is accessible via `OneSignal.User` and provides access to us | `OneSignal.User.removeTags(["KEY_01", "KEY_02"]);` | *Remove multiple tags with the provided keys from the current user.* | | `OneSignal.User.getTags();` | *Returns the local tags for the current user.* | | `OneSignal.User.addEventListener("change", (event: UserChangedState) => void);`

***See below for usage*** | *Add a User State callback which contains the nullable onesignalId and externalId. The listener will be fired when these values change.* | -| `OneSignal.User.getOnesignalId();` | *Returns the nullable OneSignal ID for the current user.* | -| `OneSignal.User.getExternalId();` | *Returns the nullable external ID for the current user.* | +| `await OneSignal.User.getOnesignalId();` | *Returns the nullable OneSignal ID for the current user.* | +| `await OneSignal.User.getExternalId();` | *Returns the nullable external ID for the current user.* | ### User State Listener From 85f507d04229d966a810e69578c8cfbd6a78dc72 Mon Sep 17 00:00:00 2001 From: Jenna Antilla <46546946+jennantilla@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:38:32 -0800 Subject: [PATCH 06/11] Add userObserverCallbackId --- src/ios/OneSignalPush.m | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ios/OneSignalPush.m b/src/ios/OneSignalPush.m index d9206b3a..b3c0d10f 100644 --- a/src/ios/OneSignalPush.m +++ b/src/ios/OneSignalPush.m @@ -45,6 +45,7 @@ NSString* inAppMessageWillDismissCallbackId; NSString* inAppMessageDidDismissCallbackId; NSString* inAppMessageClickedCallbackId; +NSString* userObserverCallbackId; OSNotificationClickEvent *actionNotification; OSNotification *notification; From e84a924424c7a27859c25cfb2ef54679d722be82 Mon Sep 17 00:00:00 2001 From: Jenna Antilla <46546946+jennantilla@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:40:31 -0800 Subject: [PATCH 07/11] Update user observer method description with instructions to check externalId --- www/UserNamespace.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/UserNamespace.ts b/www/UserNamespace.ts index 761bf9f4..df8c398b 100644 --- a/www/UserNamespace.ts +++ b/www/UserNamespace.ts @@ -179,7 +179,8 @@ export default class User { }; /** - * Add a callback that fires when the OneSignal User state changes. + * Add a callback that fires when the OneSignal User state changes. + * Important: When using the observer to retrieve the onesignalId, check the externalId as well to confirm the values are associated with the expected user. * @param {(event: UserChangedState)=>void} listener * @returns void */ From 846efc5955110bcd225963e950eaf235030a029e Mon Sep 17 00:00:00 2001 From: Jenna Antilla <46546946+jennantilla@users.noreply.github.com> Date: Thu, 8 Feb 2024 10:03:02 -0800 Subject: [PATCH 08/11] Update Id getters to async --- www/UserNamespace.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/UserNamespace.ts b/www/UserNamespace.ts index df8c398b..2f79c176 100644 --- a/www/UserNamespace.ts +++ b/www/UserNamespace.ts @@ -208,7 +208,7 @@ export default class User { * Get the nullable OneSignal Id associated with the current user. * @returns {Promise} */ - getOnesignalId(): Promise { + async getOnesignalId(): Promise { return new Promise((resolve, reject) => { const callback = (response: {value: string}) => { resolve(response.value ? response.value : null) @@ -221,7 +221,7 @@ export default class User { * Get the nullable External Id associated with the current user. * @returns {Promise} */ - getExternalId(): Promise { + async getExternalId(): Promise { return new Promise((resolve, reject) => { const callback = (response: {value: string}) => { resolve(response.value ? response.value : null) From 767cede12868d656c159a9660ee184679d239438 Mon Sep 17 00:00:00 2001 From: Jenna Antilla <46546946+jennantilla@users.noreply.github.com> Date: Thu, 8 Feb 2024 10:03:20 -0800 Subject: [PATCH 09/11] Update Migration Guide Update Migration Guide --- MIGRATION_GUIDE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 33ae5ba6..9a45ab76 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -223,8 +223,8 @@ The User name space is accessible via `OneSignal.User` and provides access to us | `OneSignal.User.removeTags(["KEY_01", "KEY_02"]);` | *Remove multiple tags with the provided keys from the current user.* | | `OneSignal.User.getTags();` | *Returns the local tags for the current user.* | | `OneSignal.User.addEventListener("change", (event: UserChangedState) => void);`

***See below for usage*** | *Add a User State callback which contains the nullable onesignalId and externalId. The listener will be fired when these values change.* | -| `await OneSignal.User.getOnesignalId();` | *Returns the nullable OneSignal ID for the current user.* | -| `await OneSignal.User.getExternalId();` | *Returns the nullable external ID for the current user.* | +| `await OneSignal.User.getOnesignalId();` | *Returns the OneSignal ID for the current user, which can be null if it is not yet available.* | +| `await OneSignal.User.getExternalId();` | *Returns the External ID for the current user, which can be null if not set.* | ### User State Listener From 12dd6c94c252a43e0ae12355d997bf894c0d0be8 Mon Sep 17 00:00:00 2001 From: Jenna Antilla <46546946+jennantilla@users.noreply.github.com> Date: Fri, 16 Feb 2024 13:26:43 -0800 Subject: [PATCH 10/11] Update observer to include null external id --- .../cordova/OneSignalObserverController.java | 13 ++++++------- src/ios/OneSignalPush.m | 10 ++++++++-- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/android/com/onesignal/cordova/OneSignalObserverController.java b/src/android/com/onesignal/cordova/OneSignalObserverController.java index 59b9108a..57ab7d53 100644 --- a/src/android/com/onesignal/cordova/OneSignalObserverController.java +++ b/src/android/com/onesignal/cordova/OneSignalObserverController.java @@ -101,14 +101,13 @@ public void onUserStateChange(UserChangedState state) { private static JSONObject createUserIds(UserState user) { JSONObject userIds = new JSONObject(); try { - if (!user.getExternalId().isEmpty()) { - userIds.put("externalId", user.getExternalId()); - } - if (!user.getOnesignalId().isEmpty()) { - userIds.put("onesignalId", user.getOnesignalId()); - } + String externalId = user.getExternalId(); + String onesignalId = user.getOnesignalId(); + + userIds.put("externalId", externalId != null && !externalId.isEmpty() ? externalId : JSONObject.NULL); + userIds.put("onesignalId", onesignalId != null && !onesignalId.isEmpty() ? onesignalId : JSONObject.NULL); } catch (JSONException e) { - e.printStackTrace(); + e.printStackTrace(); } return userIds; } diff --git a/src/ios/OneSignalPush.m b/src/ios/OneSignalPush.m index b3c0d10f..8fc9f7e4 100644 --- a/src/ios/OneSignalPush.m +++ b/src/ios/OneSignalPush.m @@ -173,11 +173,17 @@ - (void)onUserStateDidChangeWithState:(OSUserChangedState * _Nonnull)state { NSMutableDictionary *result = [NSMutableDictionary new]; NSMutableDictionary *currentObject = [NSMutableDictionary new]; - if (onesignalId.length > 0) { + + if (onesignalId && ![onesignalId isEqualToString:@""]) { currentObject[@"onesignalId"] = onesignalId; + } else { + currentObject[@"onesignalId"] = [NSNull null]; } - if (externalId.length > 0) { + + if (externalId && ![externalId isEqualToString:@""]) { currentObject[@"externalId"] = externalId; + } else { + currentObject[@"externalId"] = [NSNull null]; } result[@"current"] = currentObject; From 2eed86795a65af27ddbd8aaffc27176c45a62eff Mon Sep 17 00:00:00 2001 From: Nan Date: Fri, 23 Feb 2024 10:15:31 -0800 Subject: [PATCH 11/11] cleanup: extract common functionality into helper methods * Extract functionality to translate `null` and empty string ("") into NULL objects, into helper methods as they are used in multiple places. --- .../cordova/OneSignalObserverController.java | 19 +++++++++++---- src/ios/OneSignalPush.m | 24 +++++++++---------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/android/com/onesignal/cordova/OneSignalObserverController.java b/src/android/com/onesignal/cordova/OneSignalObserverController.java index 57ab7d53..88e298bd 100644 --- a/src/android/com/onesignal/cordova/OneSignalObserverController.java +++ b/src/android/com/onesignal/cordova/OneSignalObserverController.java @@ -76,15 +76,15 @@ public static boolean addUserStateObserver(CallbackContext callbackContext) { userStateObserver = new IUserStateObserver() { @Override public void onUserStateChange(UserChangedState state) { - UserState user = state.getCurrent(); + UserState current = state.getCurrent(); - if (!(user instanceof UserState)) { + if (!(current instanceof UserState)) { return; } try { JSONObject hash = new JSONObject(); - hash.put("current", createUserIds(state.getCurrent())); + hash.put("current", createUserIds(current)); CallbackHelper.callbackSuccess(jsUserObserverCallBack, hash); @@ -98,14 +98,23 @@ public void onUserStateChange(UserChangedState state) { return true; } + /** Helper method to return JSONObject.NULL if string is empty or nil **/ + private static Object getStringOrJSONObjectNull(String str) { + if (str != null && !str.isEmpty()) { + return str; + } else { + return JSONObject.NULL; + } + } + private static JSONObject createUserIds(UserState user) { JSONObject userIds = new JSONObject(); try { String externalId = user.getExternalId(); String onesignalId = user.getOnesignalId(); - userIds.put("externalId", externalId != null && !externalId.isEmpty() ? externalId : JSONObject.NULL); - userIds.put("onesignalId", onesignalId != null && !onesignalId.isEmpty() ? onesignalId : JSONObject.NULL); + userIds.put("externalId", getStringOrJSONObjectNull(externalId)); + userIds.put("onesignalId", getStringOrJSONObjectNull(onesignalId)); } catch (JSONException e) { e.printStackTrace(); } diff --git a/src/ios/OneSignalPush.m b/src/ios/OneSignalPush.m index 8fc9f7e4..edc0ea50 100644 --- a/src/ios/OneSignalPush.m +++ b/src/ios/OneSignalPush.m @@ -105,6 +105,16 @@ void initOneSignalObject(NSDictionary* launchOptions) { initialLaunchFired = true; } +/** Helper method to return NSNull if string is empty or nil **/ +NSString* getStringOrNSNull(NSString* string) { + // length method can be used on nil and strings + if (string.length > 0) { + return string; + } else { + return [NSNull null]; + } +} + @implementation UIApplication(OneSignalCordovaPush) static void injectSelectorCordova(Class newClass, SEL newSel, Class addToClass, SEL makeLikeSel) { @@ -174,18 +184,8 @@ - (void)onUserStateDidChangeWithState:(OSUserChangedState * _Nonnull)state { NSMutableDictionary *currentObject = [NSMutableDictionary new]; - if (onesignalId && ![onesignalId isEqualToString:@""]) { - currentObject[@"onesignalId"] = onesignalId; - } else { - currentObject[@"onesignalId"] = [NSNull null]; - } - - if (externalId && ![externalId isEqualToString:@""]) { - currentObject[@"externalId"] = externalId; - } else { - currentObject[@"externalId"] = [NSNull null]; - } - + currentObject[@"onesignalId"] = getStringOrNSNull(onesignalId); + currentObject[@"externalId"] = getStringOrNSNull(externalId); result[@"current"] = currentObject; successCallback(userObserverCallbackId, result);