diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0ec27730..5d90a3d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,12 @@ -name: Test - +name: Run Checks on: pull_request: + branches: + - '**' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: build: @@ -10,6 +15,27 @@ jobs: - name: 'Checkout' uses: actions/checkout@v5 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + - name: Setup Homebrew + uses: Homebrew/actions/setup-homebrew@main + + - name: Setup Clang + uses: tecolicom/actions-use-homebrew-tools@v1 + with: + tools: clang-format + cache: yes + + - name: Link clang-format + run: | + brew link --overwrite --force clang-format >/dev/null + export PATH="/home/linuxbrew/.linuxbrew/bin:$PATH" + clang-format --version + - name: 'Setup Bun' uses: oven-sh/setup-bun@v2 with: diff --git a/.gitignore b/.gitignore index 4a13b123..2a61c156 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,8 @@ coverage/ # tsc / build # +.gradle +build dist android/build *.tgz diff --git a/android/src/main/java/com/onesignal/rnonesignalandroid/RNOneSignal.java b/android/src/main/java/com/onesignal/rnonesignalandroid/RNOneSignal.java index 773a8a3e..332ad64a 100644 --- a/android/src/main/java/com/onesignal/rnonesignalandroid/RNOneSignal.java +++ b/android/src/main/java/com/onesignal/rnonesignalandroid/RNOneSignal.java @@ -36,10 +36,7 @@ of this software and associated documentation files (the "Software"), to deal package com.onesignal.rnonesignalandroid; import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.os.Bundle; -import com.onesignal.debug.internal.logging.Logging; -import com.facebook.react.bridge.Callback; +import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; @@ -48,46 +45,41 @@ of this software and associated documentation files (the "Software"), to deal import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.modules.core.DeviceEventManagerModule; import com.facebook.react.bridge.WritableMap; -import com.facebook.react.bridge.Arguments; +import com.facebook.react.modules.core.DeviceEventManagerModule; import com.onesignal.Continue; import com.onesignal.OneSignal; -import com.onesignal.debug.LogLevel; import com.onesignal.common.OneSignalWrapper; -import com.onesignal.inAppMessages.IInAppMessage; -import com.onesignal.inAppMessages.IInAppMessageClickListener; +import com.onesignal.debug.LogLevel; +import com.onesignal.debug.internal.logging.Logging; import com.onesignal.inAppMessages.IInAppMessageClickEvent; -import com.onesignal.inAppMessages.IInAppMessageClickResult; -import com.onesignal.inAppMessages.IInAppMessageLifecycleListener; -import com.onesignal.inAppMessages.IInAppMessageWillDisplayEvent; +import com.onesignal.inAppMessages.IInAppMessageClickListener; +import com.onesignal.inAppMessages.IInAppMessageDidDismissEvent; import com.onesignal.inAppMessages.IInAppMessageDidDisplayEvent; +import com.onesignal.inAppMessages.IInAppMessageLifecycleListener; import com.onesignal.inAppMessages.IInAppMessageWillDismissEvent; -import com.onesignal.inAppMessages.IInAppMessageDidDismissEvent; +import com.onesignal.inAppMessages.IInAppMessageWillDisplayEvent; import com.onesignal.notifications.INotification; -import com.onesignal.notifications.INotificationClickListener; import com.onesignal.notifications.INotificationClickEvent; +import com.onesignal.notifications.INotificationClickListener; import com.onesignal.notifications.INotificationLifecycleListener; import com.onesignal.notifications.INotificationWillDisplayEvent; import com.onesignal.notifications.IPermissionObserver; +import com.onesignal.user.state.IUserStateObserver; +import com.onesignal.user.state.UserChangedState; import com.onesignal.user.subscriptions.IPushSubscription; import com.onesignal.user.subscriptions.IPushSubscriptionObserver; -import com.onesignal.user.subscriptions.PushSubscriptionState; import com.onesignal.user.subscriptions.PushSubscriptionChangedState; -import com.onesignal.user.state.UserState; -import com.onesignal.user.state.UserChangedState; -import com.onesignal.user.state.IUserStateObserver; -import org.json.JSONException; - import java.util.HashMap; import java.util.Map; +import org.json.JSONException; -public class RNOneSignal extends ReactContextBaseJavaModule implements - IPushSubscriptionObserver, - IPermissionObserver, - IUserStateObserver, - LifecycleEventListener, - INotificationLifecycleListener{ +public class RNOneSignal extends ReactContextBaseJavaModule + implements IPushSubscriptionObserver, + IPermissionObserver, + IUserStateObserver, + LifecycleEventListener, + INotificationLifecycleListener { private ReactApplicationContext mReactApplicationContext; private ReactContext mReactContext; @@ -108,7 +100,9 @@ public class RNOneSignal extends ReactContextBaseJavaModule implements @Override public void onClick(IInAppMessageClickEvent event) { try { - sendEvent("OneSignal-inAppMessageClicked", RNUtils.convertHashMapToWritableMap(RNUtils.convertInAppMessageClickEventToMap(event))); + sendEvent( + "OneSignal-inAppMessageClicked", + RNUtils.convertHashMapToWritableMap(RNUtils.convertInAppMessageClickEventToMap(event))); } catch (JSONException e) { e.printStackTrace(); } @@ -119,7 +113,9 @@ public void onClick(IInAppMessageClickEvent event) { @Override public void onWillDisplay(IInAppMessageWillDisplayEvent event) { try { - sendEvent("OneSignal-inAppMessageWillDisplay", RNUtils.convertHashMapToWritableMap(RNUtils.convertInAppMessageWillDisplayEventToMap(event))); + sendEvent( + "OneSignal-inAppMessageWillDisplay", + RNUtils.convertHashMapToWritableMap(RNUtils.convertInAppMessageWillDisplayEventToMap(event))); } catch (JSONException e) { e.printStackTrace(); } @@ -128,7 +124,9 @@ public void onWillDisplay(IInAppMessageWillDisplayEvent event) { @Override public void onDidDisplay(IInAppMessageDidDisplayEvent event) { try { - sendEvent("OneSignal-inAppMessageDidDisplay", RNUtils.convertHashMapToWritableMap(RNUtils.convertInAppMessageDidDisplayEventToMap(event))); + sendEvent( + "OneSignal-inAppMessageDidDisplay", + RNUtils.convertHashMapToWritableMap(RNUtils.convertInAppMessageDidDisplayEventToMap(event))); } catch (JSONException e) { e.printStackTrace(); } @@ -137,7 +135,9 @@ public void onDidDisplay(IInAppMessageDidDisplayEvent event) { @Override public void onWillDismiss(IInAppMessageWillDismissEvent event) { try { - sendEvent("OneSignal-inAppMessageWillDismiss", RNUtils.convertHashMapToWritableMap(RNUtils.convertInAppMessageWillDismissEventToMap(event))); + sendEvent( + "OneSignal-inAppMessageWillDismiss", + RNUtils.convertHashMapToWritableMap(RNUtils.convertInAppMessageWillDismissEventToMap(event))); } catch (JSONException e) { e.printStackTrace(); } @@ -146,7 +146,9 @@ public void onWillDismiss(IInAppMessageWillDismissEvent event) { @Override public void onDidDismiss(IInAppMessageDidDismissEvent event) { try { - sendEvent("OneSignal-inAppMessageDidDismiss", RNUtils.convertHashMapToWritableMap(RNUtils.convertInAppMessageDidDismissEventToMap(event))); + sendEvent( + "OneSignal-inAppMessageDidDismiss", + RNUtils.convertHashMapToWritableMap(RNUtils.convertInAppMessageDidDismissEventToMap(event))); } catch (JSONException e) { e.printStackTrace(); } @@ -157,7 +159,9 @@ public void onDidDismiss(IInAppMessageDidDismissEvent event) { @Override public void onClick(INotificationClickEvent event) { try { - sendEvent("OneSignal-notificationClicked", RNUtils.convertHashMapToWritableMap(RNUtils.convertNotificationClickEventToMap(event))); + sendEvent( + "OneSignal-notificationClicked", + RNUtils.convertHashMapToWritableMap(RNUtils.convertNotificationClickEventToMap(event))); } catch (JSONException e) { e.printStackTrace(); } @@ -171,7 +175,7 @@ private void removeObservers() { } private void removeHandlers() { - if(!oneSignalInitDone) { + if (!oneSignalInitDone) { Logging.debug("OneSignal React-Native SDK not initialized yet. Could not remove handlers.", null); return; } @@ -187,7 +191,9 @@ private void removeHandlers() { } private void sendEvent(String eventName, Object params) { - mReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params); + mReactContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit(eventName, params); } public RNOneSignal(ReactApplicationContext reactContext) { @@ -199,7 +205,6 @@ public RNOneSignal(ReactApplicationContext reactContext) { preventDefaultCache = new HashMap(); } - /** Native Module Overrides */ @Override public String getName() { @@ -257,7 +262,6 @@ public void setPrivacyConsentRequired(Boolean required) { OneSignal.setConsentRequired(required); } - // OneSignal.Debug namespace methods @ReactMethod public void setLogLevel(int logLevel) { @@ -269,7 +273,6 @@ public void setAlertLevel(int logLevel) { OneSignal.getDebug().setAlertLevel(LogLevel.fromInt(logLevel)); } - // OneSignal.InAppMessages namespace methods @ReactMethod public void addInAppMessageClickListener() { @@ -322,7 +325,6 @@ public void clearTriggers() { OneSignal.getInAppMessages().clearTriggers(); } - // OneSignal.Location namespace methods @ReactMethod public void requestLocationPermission() { @@ -339,7 +341,6 @@ public void setLocationShared(Boolean shared) { OneSignal.getLocation().setShared(shared); } - // OneSignal.Notifications namespace methods @ReactMethod public void addNotificationClickListener() { @@ -373,9 +374,9 @@ public void onWillDisplay(INotificationWillDisplayEvent event) { event.preventDefault(); try { - sendEvent("OneSignal-notificationWillDisplayInForeground", - RNUtils.convertHashMapToWritableMap( - RNUtils.convertNotificationToMap(notification))); + sendEvent( + "OneSignal-notificationWillDisplayInForeground", + RNUtils.convertHashMapToWritableMap(RNUtils.convertNotificationToMap(notification))); try { synchronized (event) { @@ -383,7 +384,7 @@ public void onWillDisplay(INotificationWillDisplayEvent event) { event.wait(); } } - } catch(InterruptedException e){ + } catch (InterruptedException e) { Logging.error("InterruptedException: " + e.toString(), null); } } catch (JSONException e) { @@ -392,10 +393,11 @@ public void onWillDisplay(INotificationWillDisplayEvent event) { } @ReactMethod - private void displayNotification(String notificationId){ + private void displayNotification(String notificationId) { INotificationWillDisplayEvent event = notificationWillDisplayCache.get(notificationId); if (event == null) { - Logging.error("Could not find onWillDisplayNotification event for notification with id: " + notificationId, null); + Logging.error( + "Could not find onWillDisplayNotification event for notification with id: " + notificationId, null); return; } event.getNotification().display(); @@ -405,7 +407,8 @@ private void displayNotification(String notificationId){ private void preventDefault(String notificationId) { INotificationWillDisplayEvent event = notificationWillDisplayCache.get(notificationId); if (event == null) { - Logging.error("Could not find onWillDisplayNotification event for notification with id: " + notificationId, null); + Logging.error( + "Could not find onWillDisplayNotification event for notification with id: " + notificationId, null); return; } event.preventDefault(); @@ -431,7 +434,9 @@ public void removePermissionObserver() { @Override public void onNotificationPermissionChange(boolean permission) { try { - sendEvent("OneSignal-permissionChanged", RNUtils.convertHashMapToWritableMap(RNUtils.convertPermissionToMap(permission))); + sendEvent( + "OneSignal-permissionChanged", + RNUtils.convertHashMapToWritableMap(RNUtils.convertPermissionToMap(permission))); Logging.debug("Sending permission change event", null); } catch (JSONException e) { e.printStackTrace(); @@ -464,8 +469,7 @@ public void hasNotificationPermission(Promise promise) { public void permissionNative(Promise promise) { if (OneSignal.getNotifications().getPermission()) { promise.resolve(2); - } - else { + } else { promise.resolve(1); } } @@ -490,13 +494,12 @@ public void removeGroupedNotifications(String id) { OneSignal.getNotifications().removeGroupedNotifications(id); } - // OneSignal.User.pushSubscription namespace methods @ReactMethod public void getPushSubscriptionId(Promise promise) { IPushSubscription pushSubscription = OneSignal.getUser().getPushSubscription(); String pushId = pushSubscription.getId(); - if (pushId != null && !pushId.isEmpty()){ + if (pushId != null && !pushId.isEmpty()) { promise.resolve(pushId); } else { promise.resolve(null); @@ -543,13 +546,14 @@ public void addPushSubscriptionObserver() { @Override public void onPushSubscriptionChange(PushSubscriptionChangedState pushSubscriptionChangedState) { try { - sendEvent("OneSignal-subscriptionChanged", + sendEvent( + "OneSignal-subscriptionChanged", RNUtils.convertHashMapToWritableMap( RNUtils.convertPushSubscriptionChangedStateToMap(pushSubscriptionChangedState))); Logging.debug("Sending subscription change event", null); } catch (JSONException e) { e.printStackTrace(); - } + } } @ReactMethod @@ -619,7 +623,7 @@ public void getTags(Promise promise) { for (Map.Entry entry : tags.entrySet()) { writableTags.putString(entry.getKey(), entry.getValue()); } - promise.resolve(writableTags); + promise.resolve(writableTags); } @ReactMethod @@ -689,7 +693,6 @@ public void getOnesignalId(Promise promise) { onesignalId = null; } promise.resolve(onesignalId); - } @ReactMethod @@ -712,13 +715,13 @@ public void addUserStateObserver() { @Override public void onUserStateChange(UserChangedState state) { try { - sendEvent("OneSignal-userStateChanged", - RNUtils.convertHashMapToWritableMap( - RNUtils.convertUserChangedStateToMap(state))); + sendEvent( + "OneSignal-userStateChanged", + RNUtils.convertHashMapToWritableMap(RNUtils.convertUserChangedStateToMap(state))); Logging.debug("Sending user state change event", null); } catch (JSONException e) { e.printStackTrace(); - } + } } @ReactMethod diff --git a/android/src/main/java/com/onesignal/rnonesignalandroid/RNUtils.java b/android/src/main/java/com/onesignal/rnonesignalandroid/RNUtils.java index e8e55f10..8a09774e 100644 --- a/android/src/main/java/com/onesignal/rnonesignalandroid/RNUtils.java +++ b/android/src/main/java/com/onesignal/rnonesignalandroid/RNUtils.java @@ -1,43 +1,34 @@ package com.onesignal.rnonesignalandroid; -import java.util.ArrayList; -import java.util.Collection; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.ReadableMapKeySetIterator; import com.facebook.react.bridge.ReadableType; -import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableMap; -import com.facebook.react.bridge.WritableNativeArray; -import com.facebook.react.bridge.WritableNativeMap; - import com.onesignal.inAppMessages.IInAppMessage; import com.onesignal.inAppMessages.IInAppMessageClickEvent; import com.onesignal.inAppMessages.IInAppMessageClickResult; -import com.onesignal.inAppMessages.IInAppMessageWillDisplayEvent; +import com.onesignal.inAppMessages.IInAppMessageDidDismissEvent; import com.onesignal.inAppMessages.IInAppMessageDidDisplayEvent; import com.onesignal.inAppMessages.IInAppMessageWillDismissEvent; -import com.onesignal.inAppMessages.IInAppMessageDidDismissEvent; +import com.onesignal.inAppMessages.IInAppMessageWillDisplayEvent; import com.onesignal.notifications.INotification; -import com.onesignal.notifications.INotificationWillDisplayEvent; import com.onesignal.notifications.INotificationClickEvent; import com.onesignal.notifications.INotificationClickResult; -import com.onesignal.notifications.INotificationReceivedEvent; -import com.onesignal.user.subscriptions.IPushSubscription; -import com.onesignal.user.subscriptions.PushSubscriptionState; -import com.onesignal.user.subscriptions.PushSubscriptionChangedState; -import com.onesignal.user.state.UserState; import com.onesignal.user.state.UserChangedState; - +import com.onesignal.user.state.UserState; +import com.onesignal.user.subscriptions.PushSubscriptionChangedState; +import com.onesignal.user.subscriptions.PushSubscriptionState; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import java.util.Iterator; -import java.util.HashMap; -import java.util.Map; -import java.util.List; -import javax.annotation.Nullable; public class RNUtils { public static WritableMap convertHashMapToWritableMap(HashMap hashMap) throws JSONException { @@ -67,11 +58,12 @@ public static WritableMap convertHashMapToWritableMap(HashMap ha return writableMap; } - public static HashMap convertNotificationClickEventToMap(INotificationClickEvent event) throws JSONException { + public static HashMap convertNotificationClickEventToMap(INotificationClickEvent event) + throws JSONException { HashMap clickResultHash = new HashMap<>(); HashMap hash = new HashMap<>(); HashMap notificationHash = convertNotificationToMap(event.getNotification()); - INotificationClickResult clickResult = event.getResult(); + INotificationClickResult clickResult = event.getResult(); clickResultHash.put("actionId", clickResult.getActionId()); clickResultHash.put("url", clickResult.getUrl()); @@ -95,33 +87,25 @@ public static HashMap convertNotificationToMap(INotification not notificationHash.put("notificationId", notification.getNotificationId()); notificationHash.put("title", notification.getTitle()); - if (notification.getBody() != null) - notificationHash.put("body", notification.getBody()); - if (notification.getSmallIcon() != null) - notificationHash.put("smallIcon", notification.getSmallIcon()); - if (notification.getLargeIcon() != null) - notificationHash.put("largeIcon", notification.getLargeIcon()); - if (notification.getBigPicture() != null) - notificationHash.put("bigPicture", notification.getBigPicture()); + if (notification.getBody() != null) notificationHash.put("body", notification.getBody()); + if (notification.getSmallIcon() != null) notificationHash.put("smallIcon", notification.getSmallIcon()); + if (notification.getLargeIcon() != null) notificationHash.put("largeIcon", notification.getLargeIcon()); + if (notification.getBigPicture() != null) notificationHash.put("bigPicture", notification.getBigPicture()); if (notification.getSmallIconAccentColor() != null) notificationHash.put("smallIconAccentColor", notification.getSmallIconAccentColor()); - if (notification.getLaunchURL() != null) - notificationHash.put("launchURL", notification.getLaunchURL()); - if (notification.getSound() != null) - notificationHash.put("sound", notification.getSound()); - if (notification.getLedColor() != null) - notificationHash.put("ledColor", notification.getLedColor()); + if (notification.getLaunchURL() != null) notificationHash.put("launchURL", notification.getLaunchURL()); + if (notification.getSound() != null) notificationHash.put("sound", notification.getSound()); + if (notification.getLedColor() != null) notificationHash.put("ledColor", notification.getLedColor()); notificationHash.put("lockScreenVisibility", notification.getLockScreenVisibility()); - if (notification.getGroupKey() != null) - notificationHash.put("groupKey", notification.getGroupKey()); + if (notification.getGroupKey() != null) notificationHash.put("groupKey", notification.getGroupKey()); if (notification.getGroupMessage() != null) notificationHash.put("groupMessage", notification.getGroupMessage()); if (notification.getFromProjectNumber() != null) notificationHash.put("fromProjectNumber", notification.getFromProjectNumber()); - if (notification.getCollapseId() != null) - notificationHash.put("collapseId", notification.getCollapseId()); + if (notification.getCollapseId() != null) notificationHash.put("collapseId", notification.getCollapseId()); notificationHash.put("priority", notification.getPriority()); - if (notification.getAdditionalData() != null && notification.getAdditionalData().length() > 0) + if (notification.getAdditionalData() != null + && notification.getAdditionalData().length() > 0) notificationHash.put("additionalData", convertJSONObjectToHashMap(notification.getAdditionalData())); if (notification.getActionButtons() != null) { notificationHash.put("actionButtons", notification.getActionButtons()); @@ -138,7 +122,8 @@ private static HashMap convertInAppMessageToMap(IInAppMessage me return hash; } - public static HashMap convertInAppMessageWillDisplayEventToMap(IInAppMessageWillDisplayEvent event) { + public static HashMap convertInAppMessageWillDisplayEventToMap( + IInAppMessageWillDisplayEvent event) { HashMap hash = new HashMap<>(); hash.put("message", convertInAppMessageToMap(event.getMessage())); @@ -152,7 +137,8 @@ public static HashMap convertInAppMessageDidDisplayEventToMap(II return hash; } - public static HashMap convertInAppMessageWillDismissEventToMap(IInAppMessageWillDismissEvent event) { + public static HashMap convertInAppMessageWillDismissEventToMap( + IInAppMessageWillDismissEvent event) { HashMap hash = new HashMap<>(); hash.put("message", convertInAppMessageToMap(event.getMessage())); @@ -192,7 +178,7 @@ public static HashMap convertPushSubscriptionStateToMap(PushSubs if (state.getId() != null && !state.getId().isEmpty()) { hash.put("id", state.getId()); } else { - hash.put("id", JSONObject.NULL); + hash.put("id", JSONObject.NULL); } hash.put("optedIn", state.getOptedIn()); @@ -204,14 +190,12 @@ public static HashMap convertUserStateToMap(UserState user) { if (user.getExternalId() != null && !user.getExternalId().isEmpty()) { hash.put("externalId", user.getExternalId()); - } - else { + } else { hash.put("externalId", JSONObject.NULL); } if (user.getOnesignalId() != null && !user.getOnesignalId().isEmpty()) { hash.put("onesignalId", user.getOnesignalId()); - } - else { + } else { hash.put("onesignalId", JSONObject.NULL); } @@ -236,23 +220,21 @@ public static HashMap convertUserChangedStateToMap(UserChangedSt public static HashMap convertJSONObjectToHashMap(JSONObject object) throws JSONException { HashMap hash = new HashMap<>(); - if (object == null || object == JSONObject.NULL) - return hash; + if (object == null || object == JSONObject.NULL) return hash; Iterator keys = object.keys(); while (keys.hasNext()) { String key = keys.next(); - if (object.isNull(key)) - continue; + if (object.isNull(key)) continue; Object val = object.get(key); if (val instanceof JSONArray) { - val = convertJSONArrayToList((JSONArray)val); + val = convertJSONArrayToList((JSONArray) val); } else if (val instanceof JSONObject) { - val = convertJSONObjectToHashMap((JSONObject)val); + val = convertJSONObjectToHashMap((JSONObject) val); } hash.put(key, val); @@ -264,8 +246,7 @@ public static HashMap convertJSONObjectToHashMap(JSONObject obje public static Collection convertReadableArrayIntoStringCollection(ReadableArray readableArray) { ArrayList strings = new ArrayList<>(); for (Object object : readableArray.toArrayList()) { - if (object instanceof String) - strings.add((String) object); + if (object instanceof String) strings.add((String) object); } return strings; } @@ -298,10 +279,8 @@ private static List convertJSONArrayToList(JSONArray array) throws JSONE for (int i = 0; i < array.length(); i++) { Object val = array.get(i); - if (val instanceof JSONArray) - val = RNUtils.convertJSONArrayToList((JSONArray)val); - else if (val instanceof JSONObject) - val = convertJSONObjectToHashMap((JSONObject)val); + if (val instanceof JSONArray) val = RNUtils.convertJSONArrayToList((JSONArray) val); + else if (val instanceof JSONObject) val = convertJSONObjectToHashMap((JSONObject) val); list.add(val); } diff --git a/android/src/main/java/com/onesignal/rnonesignalandroid/ReactNativeOneSignalPackage.java b/android/src/main/java/com/onesignal/rnonesignalandroid/ReactNativeOneSignalPackage.java index 2ef245d2..73a8daa9 100644 --- a/android/src/main/java/com/onesignal/rnonesignalandroid/ReactNativeOneSignalPackage.java +++ b/android/src/main/java/com/onesignal/rnonesignalandroid/ReactNativeOneSignalPackage.java @@ -5,11 +5,10 @@ import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.uimanager.ViewManager; - import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Arrays; public class ReactNativeOneSignalPackage implements ReactPackage { @Override diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..3168af42 --- /dev/null +++ b/build.gradle @@ -0,0 +1,43 @@ +buildscript { + repositories { + google() + mavenCentral() + } + dependencies { + classpath 'com.diffplug.spotless:spotless-plugin-gradle:6.25.0' + } +} + +repositories { + google() + mavenCentral() +} + +apply plugin: 'com.diffplug.spotless' + +spotless { + java { + target 'android/**/*.java', 'examples/RNOneSignalTS/android/app/src/**/*.java' + targetExclude '**/build/**' + palantirJavaFormat('2.28.0') + removeUnusedImports() + trimTrailingWhitespace() + endWithNewline() + } + + cpp { + target 'ios/**/*.m', 'ios/**/*.h' + def clangVersion = "clang-format --version".execute().text.trim().split(" ")[2] + clangFormat(clangVersion) + trimTrailingWhitespace() + endWithNewline() + } + + format 'xml', { + target '**/*.xml' + trimTrailingWhitespace() + indentWithSpaces(4) + endWithNewline() + } +} + diff --git a/bun.lock b/bun.lock index 257e04ff..87862bfe 100644 --- a/bun.lock +++ b/bun.lock @@ -11,6 +11,7 @@ "@types/invariant": "^2.2.37", "@types/react-native": "^0.73.0", "@vitest/coverage-v8": "4.0.8", + "concurrently": "^9.2.1", "oxlint": "^1.26.0", "prettier": "^3.6.2", "typescript": "^5.9.3", @@ -373,7 +374,7 @@ "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], + "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], @@ -441,6 +442,8 @@ "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], + "concurrently": ["concurrently@9.2.1", "", { "dependencies": { "chalk": "4.1.2", "rxjs": "7.8.2", "shell-quote": "1.8.3", "supports-color": "8.1.1", "tree-kill": "1.2.2", "yargs": "17.7.2" }, "bin": { "conc": "dist/bin/concurrently.js", "concurrently": "dist/bin/concurrently.js" } }, "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng=="], + "confbox": ["confbox@0.2.2", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="], "connect": ["connect@3.7.0", "", { "dependencies": { "debug": "2.6.9", "finalhandler": "1.1.2", "parseurl": "~1.3.3", "utils-merge": "1.0.1" } }, "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ=="], @@ -787,6 +790,8 @@ "rollup": ["rollup@4.52.5", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.52.5", "@rollup/rollup-android-arm64": "4.52.5", "@rollup/rollup-darwin-arm64": "4.52.5", "@rollup/rollup-darwin-x64": "4.52.5", "@rollup/rollup-freebsd-arm64": "4.52.5", "@rollup/rollup-freebsd-x64": "4.52.5", "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", "@rollup/rollup-linux-arm-musleabihf": "4.52.5", "@rollup/rollup-linux-arm64-gnu": "4.52.5", "@rollup/rollup-linux-arm64-musl": "4.52.5", "@rollup/rollup-linux-loong64-gnu": "4.52.5", "@rollup/rollup-linux-ppc64-gnu": "4.52.5", "@rollup/rollup-linux-riscv64-gnu": "4.52.5", "@rollup/rollup-linux-riscv64-musl": "4.52.5", "@rollup/rollup-linux-s390x-gnu": "4.52.5", "@rollup/rollup-linux-x64-gnu": "4.52.5", "@rollup/rollup-linux-x64-musl": "4.52.5", "@rollup/rollup-openharmony-arm64": "4.52.5", "@rollup/rollup-win32-arm64-msvc": "4.52.5", "@rollup/rollup-win32-ia32-msvc": "4.52.5", "@rollup/rollup-win32-x64-gnu": "4.52.5", "@rollup/rollup-win32-x64-msvc": "4.52.5", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw=="], + "rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="], + "scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="], "semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], @@ -839,7 +844,7 @@ "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], - "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + "supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], @@ -863,6 +868,10 @@ "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], + "tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="], + + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "type-detect": ["type-detect@4.0.8", "", {}, "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="], "type-fest": ["type-fest@0.7.1", "", {}, "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="], @@ -939,8 +948,6 @@ "@rushstack/node-core-library/semver": ["semver@7.5.4", "", { "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" } }, "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA=="], - "@rushstack/terminal/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], - "@vue/compiler-core/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], "@vue/language-core/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], @@ -949,7 +956,7 @@ "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + "chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], "connect/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], @@ -963,12 +970,12 @@ "istanbul-lib-instrument/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], + "istanbul-lib-report/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + "jest-util/ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="], "jest-util/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], - "lighthouse-logger/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], "loose-envify/js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], @@ -985,6 +992,8 @@ "mlly/pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], + "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], + "react-devtools-core/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], "send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], @@ -1001,8 +1010,6 @@ "test-exclude/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], - "wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], "connect/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], diff --git a/ios/RCTOneSignal/RCTOneSignal.h b/ios/RCTOneSignal/RCTOneSignal.h index be93f668..c470f1a3 100644 --- a/ios/RCTOneSignal/RCTOneSignal.h +++ b/ios/RCTOneSignal/RCTOneSignal.h @@ -5,7 +5,10 @@ #import "../OneSignalFramework.h" #endif -@interface RCTOneSignal : NSObject -+ (RCTOneSignal *) sharedInstance; +@interface RCTOneSignal + : NSObject ++ (RCTOneSignal *)sharedInstance; @end diff --git a/ios/RCTOneSignal/RCTOneSignal.m b/ios/RCTOneSignal/RCTOneSignal.m index e03ed093..dd49fa06 100644 --- a/ios/RCTOneSignal/RCTOneSignal.m +++ b/ios/RCTOneSignal/RCTOneSignal.m @@ -1,11 +1,11 @@ #if __has_include() -#import #import +#import #import #import #else -#import "RCTConvert.h" #import "RCTBridge.h" +#import "RCTConvert.h" #import "RCTEventDispatcher.h" #import "RCTUtils.h" #endif @@ -18,8 +18,8 @@ #define UIUserNotificationTypeAlert UIRemoteNotificationTypeAlert #define UIUserNotificationTypeBadge UIRemoteNotificationTypeBadge #define UIUserNotificationTypeSound UIRemoteNotificationTypeSound -#define UIUserNotificationTypeNone UIRemoteNotificationTypeNone -#define UIUserNotificationType UIRemoteNotificationType +#define UIUserNotificationTypeNone UIRemoteNotificationTypeNone +#define UIUserNotificationType UIRemoteNotificationType #endif @@ -27,131 +27,157 @@ @interface RCTOneSignal () @end @implementation RCTOneSignal { - BOOL didInitialize; + BOOL didInitialize; } -OSNotificationClickResult* coldStartOSNotificationClickResult; +OSNotificationClickResult *coldStartOSNotificationClickResult; -+ (RCTOneSignal *) sharedInstance { - static dispatch_once_t token = 0; - static id _sharedInstance = nil; - dispatch_once(&token, ^{ - _sharedInstance = [[RCTOneSignal alloc] init]; - }); - return _sharedInstance; ++ (RCTOneSignal *)sharedInstance { + static dispatch_once_t token = 0; + static id _sharedInstance = nil; + dispatch_once(&token, ^{ + _sharedInstance = [[RCTOneSignal alloc] init]; + }); + return _sharedInstance; } - (void)initOneSignal:(NSDictionary *)launchOptions { - if (didInitialize) - return; + if (didInitialize) + return; - OneSignalWrapper.sdkType = @"reactnative"; - OneSignalWrapper.sdkVersion = @"050213"; - // initialize the SDK with a nil app ID so cold start click listeners can be triggered - [OneSignal initialize:nil withLaunchOptions:launchOptions]; - didInitialize = true; + OneSignalWrapper.sdkType = @"reactnative"; + OneSignalWrapper.sdkVersion = @"050213"; + // initialize the SDK with a nil app ID so cold start click listeners can be + // triggered + [OneSignal initialize:nil withLaunchOptions:launchOptions]; + didInitialize = true; } - (void)handleRemoteNotificationOpened:(NSString *)result { - NSDictionary *json = [self jsonObjectWithString:result]; + NSDictionary *json = [self jsonObjectWithString:result]; - if (json) { - [self sendEvent:OSEventString(NotificationClicked) withBody:json]; - } + if (json) { + [self sendEvent:OSEventString(NotificationClicked) withBody:json]; + } } - (NSDictionary *)jsonObjectWithString:(NSString *)jsonString { - NSError *jsonError; - NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; - NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonError]; + NSError *jsonError; + NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; + NSDictionary *json = + [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingMutableContainers + error:&jsonError]; - if (jsonError) { - return nil; - } + if (jsonError) { + return nil; + } - return json; + return json; } - (void)sendEvent:(NSString *)eventName withBody:(NSDictionary *)body { - [RCTOneSignalEventEmitter sendEventWithName:eventName withBody:body]; -} - -- (void)onUserStateDidChangeWithState:(OSUserChangedState * _Nonnull)state { - NSString *onesignalId = state.current.onesignalId; - NSString *externalId = state.current.externalId; - - NSMutableDictionary *currentDictionary = [NSMutableDictionary dictionary]; - - if (onesignalId.length > 0) { - [currentDictionary setObject:onesignalId forKey:@"onesignalId"]; - } - else { - [currentDictionary setObject:[NSNull null] forKey:@"onesignalId"]; - } - - if (externalId.length > 0) { - [currentDictionary setObject:externalId forKey:@"externalId"]; - } - else { - [currentDictionary setObject:[NSNull null] forKey:@"externalId"]; - } - - NSDictionary *result = @{@"current": currentDictionary}; - - [self sendEvent:OSEventString(UserStateChanged) withBody:result]; -} - -- (void)onPushSubscriptionDidChangeWithState:(OSPushSubscriptionChangedState * _Nonnull)state { - NSMutableDictionary *result = [NSMutableDictionary new]; - - //Previous state - NSMutableDictionary *previousObject = [NSMutableDictionary new]; - previousObject[@"token"] = (state.previous.token && ![state.previous.token isEqualToString:@""]) ? state.previous.token : [NSNull null]; - previousObject[@"id"] = (state.previous.id && ![state.previous.id isEqualToString:@""]) ? state.previous.id : [NSNull null]; - previousObject[@"optedIn"] = @(state.previous.optedIn); - result[@"previous"] = previousObject; - - //Current state - NSMutableDictionary *currentObject = [NSMutableDictionary new]; - currentObject[@"token"] = (state.current.token && ![state.current.token isEqualToString:@""]) ? state.current.token : [NSNull null]; - currentObject[@"id"] = (state.current.id && ![state.current.id isEqualToString:@""]) ? state.current.id : [NSNull null]; - currentObject[@"optedIn"] = @(state.current.optedIn); - result[@"current"] = currentObject; - - [self sendEvent:OSEventString(SubscriptionChanged) withBody:result]; + [RCTOneSignalEventEmitter sendEventWithName:eventName withBody:body]; +} + +- (void)onUserStateDidChangeWithState:(OSUserChangedState *_Nonnull)state { + NSString *onesignalId = state.current.onesignalId; + NSString *externalId = state.current.externalId; + + NSMutableDictionary *currentDictionary = [NSMutableDictionary dictionary]; + + if (onesignalId.length > 0) { + [currentDictionary setObject:onesignalId forKey:@"onesignalId"]; + } else { + [currentDictionary setObject:[NSNull null] forKey:@"onesignalId"]; + } + + if (externalId.length > 0) { + [currentDictionary setObject:externalId forKey:@"externalId"]; + } else { + [currentDictionary setObject:[NSNull null] forKey:@"externalId"]; + } + + NSDictionary *result = @{@"current" : currentDictionary}; + + [self sendEvent:OSEventString(UserStateChanged) withBody:result]; +} + +- (void)onPushSubscriptionDidChangeWithState: + (OSPushSubscriptionChangedState *_Nonnull)state { + NSMutableDictionary *result = [NSMutableDictionary new]; + + // Previous state + NSMutableDictionary *previousObject = [NSMutableDictionary new]; + previousObject[@"token"] = + (state.previous.token && ![state.previous.token isEqualToString:@""]) + ? state.previous.token + : [NSNull null]; + previousObject[@"id"] = + (state.previous.id && ![state.previous.id isEqualToString:@""]) + ? state.previous.id + : [NSNull null]; + previousObject[@"optedIn"] = @(state.previous.optedIn); + result[@"previous"] = previousObject; + + // Current state + NSMutableDictionary *currentObject = [NSMutableDictionary new]; + currentObject[@"token"] = + (state.current.token && ![state.current.token isEqualToString:@""]) + ? state.current.token + : [NSNull null]; + currentObject[@"id"] = + (state.current.id && ![state.current.id isEqualToString:@""]) + ? state.current.id + : [NSNull null]; + currentObject[@"optedIn"] = @(state.current.optedIn); + result[@"current"] = currentObject; + + [self sendEvent:OSEventString(SubscriptionChanged) withBody:result]; } - (void)onNotificationPermissionDidChange:(BOOL)permission { - [self sendEvent:OSEventString(PermissionChanged) withBody:@{@"permission": @(permission)}]; + [self sendEvent:OSEventString(PermissionChanged) + withBody:@{@"permission" : @(permission)}]; } -- (void)onClickNotification:(OSNotificationClickEvent * _Nonnull)event { - [self sendEvent:OSEventString(NotificationClicked) withBody:[event jsonRepresentation]]; +- (void)onClickNotification:(OSNotificationClickEvent *_Nonnull)event { + [self sendEvent:OSEventString(NotificationClicked) + withBody:[event jsonRepresentation]]; } -- (void)onClickInAppMessage:(OSInAppMessageClickEvent * _Nonnull)event { - [self sendEvent:OSEventString(InAppMessageClicked) withBody:[event jsonRepresentation]]; +- (void)onClickInAppMessage:(OSInAppMessageClickEvent *_Nonnull)event { + [self sendEvent:OSEventString(InAppMessageClicked) + withBody:[event jsonRepresentation]]; } -- (void)onWillDisplayInAppMessage:(OSInAppMessageWillDisplayEvent * _Nonnull)event { - [self sendEvent:OSEventString(InAppMessageWillDisplay) withBody:[event jsonRepresentation]]; +- (void)onWillDisplayInAppMessage: + (OSInAppMessageWillDisplayEvent *_Nonnull)event { + [self sendEvent:OSEventString(InAppMessageWillDisplay) + withBody:[event jsonRepresentation]]; } -- (void)onDidDisplayInAppMessage:(OSInAppMessageDidDisplayEvent * _Nonnull)event { - [self sendEvent:OSEventString(InAppMessageDidDisplay) withBody:[event jsonRepresentation]]; +- (void)onDidDisplayInAppMessage: + (OSInAppMessageDidDisplayEvent *_Nonnull)event { + [self sendEvent:OSEventString(InAppMessageDidDisplay) + withBody:[event jsonRepresentation]]; } -- (void)onWillDismissInAppMessage:(OSInAppMessageWillDismissEvent * _Nonnull)event { - [self sendEvent:OSEventString(InAppMessageWillDismiss) withBody:[event jsonRepresentation]]; +- (void)onWillDismissInAppMessage: + (OSInAppMessageWillDismissEvent *_Nonnull)event { + [self sendEvent:OSEventString(InAppMessageWillDismiss) + withBody:[event jsonRepresentation]]; } -- (void)onDidDismissInAppMessage:(OSInAppMessageDidDismissEvent * _Nonnull)event { - [self sendEvent:OSEventString(InAppMessageDidDismiss) withBody:[event jsonRepresentation]]; +- (void)onDidDismissInAppMessage: + (OSInAppMessageDidDismissEvent *_Nonnull)event { + [self sendEvent:OSEventString(InAppMessageDidDismiss) + withBody:[event jsonRepresentation]]; } - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; + [[NSNotificationCenter defaultCenter] removeObserver:self]; } @end diff --git a/ios/RCTOneSignal/RCTOneSignalEventEmitter.h b/ios/RCTOneSignal/RCTOneSignalEventEmitter.h index ca153320..5e4a8f2a 100644 --- a/ios/RCTOneSignal/RCTOneSignalEventEmitter.h +++ b/ios/RCTOneSignal/RCTOneSignalEventEmitter.h @@ -1,31 +1,39 @@ #if __has_include() #import -#import #import #import +#import #import #elif __has_include("RCTBridgeModule.h") #import "RCTBridgeModule.h" -#import "RCTEventEmitter.h" #import "RCTConvert.h" #import "RCTEventDispatcher.h" +#import "RCTEventEmitter.h" #import "RCTUtils.h" #endif typedef NS_ENUM(NSInteger, OSNotificationEventTypes) { - PermissionChanged, - SubscriptionChanged, - UserStateChanged, - NotificationWillDisplayInForeground, - NotificationClicked, - InAppMessageClicked, - InAppMessageWillDisplay, - InAppMessageDidDisplay, - InAppMessageWillDismiss, - InAppMessageDidDismiss, + PermissionChanged, + SubscriptionChanged, + UserStateChanged, + NotificationWillDisplayInForeground, + NotificationClicked, + InAppMessageClicked, + InAppMessageWillDisplay, + InAppMessageDidDisplay, + InAppMessageWillDismiss, + InAppMessageDidDismiss, }; -#define OSNotificationEventTypesArray @[@"OneSignal-permissionChanged",@"OneSignal-subscriptionChanged",@"OneSignal-userStateChanged",@"OneSignal-notificationWillDisplayInForeground",@"OneSignal-notificationClicked",@"OneSignal-inAppMessageClicked", @"OneSignal-inAppMessageWillDisplay", @"OneSignal-inAppMessageDidDisplay", @"OneSignal-inAppMessageWillDismiss", @"OneSignal-inAppMessageDidDismiss"] +#define OSNotificationEventTypesArray \ + @[ \ + @"OneSignal-permissionChanged", @"OneSignal-subscriptionChanged", \ + @"OneSignal-userStateChanged", \ + @"OneSignal-notificationWillDisplayInForeground", \ + @"OneSignal-notificationClicked", @"OneSignal-inAppMessageClicked", \ + @"OneSignal-inAppMessageWillDisplay", @"OneSignal-inAppMessageDidDisplay", \ + @"OneSignal-inAppMessageWillDismiss", @"OneSignal-inAppMessageDidDismiss" \ + ] #define OSEventString(enum) [OSNotificationEventTypesArray objectAtIndex:enum] diff --git a/ios/RCTOneSignal/RCTOneSignalEventEmitter.m b/ios/RCTOneSignal/RCTOneSignalEventEmitter.m index 50bc26a4..a6c53a46 100644 --- a/ios/RCTOneSignal/RCTOneSignalEventEmitter.m +++ b/ios/RCTOneSignal/RCTOneSignalEventEmitter.m @@ -1,32 +1,31 @@ #import "RCTOneSignalEventEmitter.h" -#import #import "OneSignalLiveActivities/OneSignalLiveActivities-Swift.h" #import "RCTOneSignal.h" +#import #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - @implementation RCTOneSignalEventEmitter { - BOOL _hasListeners; - BOOL _hasSetSubscriptionObserver; - BOOL _hasSetPermissionObserver; - BOOL _hasSetUserStateObserver; - BOOL _hasAddedNotificationClickListener; - BOOL _hasAddedNotificationForegroundLifecycleListener; - BOOL _hasAddedInAppMessageClickListener; - BOOL _hasAddedInAppMessageLifecycleListener; - NSMutableDictionary* _preventDefaultCache; - NSMutableDictionary* _notificationWillDisplayCache; + BOOL _hasListeners; + BOOL _hasSetSubscriptionObserver; + BOOL _hasSetPermissionObserver; + BOOL _hasSetUserStateObserver; + BOOL _hasAddedNotificationClickListener; + BOOL _hasAddedNotificationForegroundLifecycleListener; + BOOL _hasAddedInAppMessageClickListener; + BOOL _hasAddedInAppMessageLifecycleListener; + NSMutableDictionary *_preventDefaultCache; + NSMutableDictionary *_notificationWillDisplayCache; } static BOOL _didStartObserving = false; + (BOOL)hasSetBridge { - return _didStartObserving; + return _didStartObserving; } -+(BOOL)requiresMainQueueSetup { - return YES; ++ (BOOL)requiresMainQueueSetup { + return YES; } /* @@ -40,492 +39,549 @@ +(BOOL)requiresMainQueueSetup { #pragma mark RCTEventEmitter Subclass Methods - (instancetype)init { - if (self = [super init]) { - _preventDefaultCache = [NSMutableDictionary new]; - _notificationWillDisplayCache = [NSMutableDictionary new]; + if (self = [super init]) { + _preventDefaultCache = [NSMutableDictionary new]; + _notificationWillDisplayCache = [NSMutableDictionary new]; - for (NSString *eventName in [self supportedEvents]) - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(emitEvent:) name:eventName object:nil]; - } + for (NSString *eventName in [self supportedEvents]) + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(emitEvent:) + name:eventName + object:nil]; + } - return self; + return self; } - (void)startObserving { - _hasListeners = true; + _hasListeners = true; - [[NSNotificationCenter defaultCenter] postNotificationName:@"didSetBridge" object:nil]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"didSetBridge" + object:nil]; - _didStartObserving = true; + _didStartObserving = true; } - (void)stopObserving { - _hasListeners = false; + _hasListeners = false; } - (NSArray *)supportedEvents { - NSMutableArray *events = [NSMutableArray new]; + NSMutableArray *events = [NSMutableArray new]; - for (int i = 0; i < OSNotificationEventTypesArray.count; i++) { - [events addObject:OSEventString(i)]; - } + for (int i = 0; i < OSNotificationEventTypesArray.count; i++) { + [events addObject:OSEventString(i)]; + } - return events; + return events; } - (NSArray *)processNSError:(NSError *)error { - if (error.userInfo[@"error"]) { - return @[error.userInfo[@"error"]]; - } else if (error.userInfo[@"returned"]) { - return @[error.userInfo[@"returned"]]; - } - - return @[error.localizedDescription]; -} + if (error.userInfo[@"error"]) { + return @[ error.userInfo[@"error"] ]; + } else if (error.userInfo[@"returned"]) { + return @[ error.userInfo[@"returned"] ]; + } + return @[ error.localizedDescription ]; +} #pragma mark Send Event Methods - (void)emitEvent:(NSNotification *)notification { - if (!_hasListeners) return; + if (!_hasListeners) + return; - [self sendEventWithName:notification.name body:notification.userInfo]; + [self sendEventWithName:notification.name body:notification.userInfo]; } + (void)sendEventWithName:(NSString *)name withBody:(NSDictionary *)body { - [[NSNotificationCenter defaultCenter] postNotificationName:name object:nil userInfo:body]; + [[NSNotificationCenter defaultCenter] postNotificationName:name + object:nil + userInfo:body]; } - #pragma mark Exported Methods // OneSignal root namespace methods -RCT_EXPORT_METHOD(initialize:(NSString* _Nonnull)appId) { - [OneSignal initialize:appId withLaunchOptions:NULL]; +RCT_EXPORT_METHOD(initialize : (NSString *_Nonnull)appId) { + [OneSignal initialize:appId withLaunchOptions:NULL]; } -RCT_EXPORT_METHOD(login:(NSString *)externalId) { - [OneSignal login:externalId]; +RCT_EXPORT_METHOD(login : (NSString *)externalId) { + [OneSignal login:externalId]; } -RCT_EXPORT_METHOD(logout) { - [OneSignal logout]; -} +RCT_EXPORT_METHOD(logout) { [OneSignal logout]; } -RCT_EXPORT_METHOD(enterLiveActivity:(NSString *)activityId - withToken:(NSString *)token - withResponse:(RCTResponseSenderBlock)callback) { - [OneSignal.LiveActivities enter:activityId withToken:token withSuccess:^(NSDictionary *result) { - callback(@[result]); - } withFailure:^(NSError *error) { +RCT_EXPORT_METHOD(enterLiveActivity : (NSString *)activityId withToken : ( + NSString *)token withResponse : (RCTResponseSenderBlock)callback) { + [OneSignal.LiveActivities enter:activityId + withToken:token + withSuccess:^(NSDictionary *result) { + callback(@[ result ]); + } + withFailure:^(NSError *error) { callback([self processNSError:error]); - }]; + }]; } -RCT_EXPORT_METHOD(exitLiveActivity:(NSString *)activityId - withResponse:(RCTResponseSenderBlock)callback) { - [OneSignal.LiveActivities exit:activityId withSuccess:^(NSDictionary *result) { - callback(@[result]); - } withFailure:^(NSError *error) { +RCT_EXPORT_METHOD(exitLiveActivity : (NSString *)activityId withResponse : ( + RCTResponseSenderBlock)callback) { + [OneSignal.LiveActivities exit:activityId + withSuccess:^(NSDictionary *result) { + callback(@[ result ]); + } + withFailure:^(NSError *error) { callback([self processNSError:error]); - }]; -} - -RCT_EXPORT_METHOD(setPushToStartToken:(NSString *)activityType - withToken:(NSString *)token) { - #if !TARGET_OS_MACCATALYST - NSError* err=nil; - if (@available(iOS 17.2, *)) { - [OneSignalLiveActivitiesManagerImpl setPushToStartToken:activityType withToken:token error:&err]; - if (err) { - [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"activityType must be the name of your ActivityAttributes struct"]]; - } - } else { - [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"cannot setPushToStartToken on iOS < 17.2"]]; + }]; +} + +RCT_EXPORT_METHOD(setPushToStartToken : (NSString *) + activityType withToken : (NSString *)token) { +#if !TARGET_OS_MACCATALYST + NSError *err = nil; + if (@available(iOS 17.2, *)) { + [OneSignalLiveActivitiesManagerImpl setPushToStartToken:activityType + withToken:token + error:&err]; + if (err) { + [OneSignalLog + onesignalLog:ONE_S_LL_ERROR + message:[NSString + stringWithFormat:@"activityType must be the name of " + @"your ActivityAttributes struct"]]; } - #endif -} - -RCT_EXPORT_METHOD(removePushToStartToken:(NSString *)activityType) { - #if !TARGET_OS_MACCATALYST - NSError* err=nil; - if (@available(iOS 17.2, *)) { - [OneSignalLiveActivitiesManagerImpl removePushToStartToken:activityType error:&err]; - if (err) { - [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"activityType must be the name of your ActivityAttributes struct"]]; - } - } else { - [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"cannot removePushToStartToken on iOS < 17.2"]]; - } - #endif -} - -RCT_EXPORT_METHOD(setupDefaultLiveActivity:(NSDictionary * _Nullable)options) { - #if !TARGET_OS_MACCATALYST - LiveActivitySetupOptions *laOptions = nil; - if (options != nil) { - laOptions = [LiveActivitySetupOptions alloc]; - [laOptions setEnablePushToStart:[options[@"enablePushToStart"] boolValue]]; - [laOptions setEnablePushToUpdate:[options[@"enablePushToUpdate"] boolValue]]; - } - - if (@available(iOS 16.1, *)) { - [OneSignalLiveActivitiesManagerImpl setupDefaultWithOptions:laOptions]; - } else { - [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"cannot setupDefault on iOS < 16.1"]]; + } else { + [OneSignalLog + onesignalLog:ONE_S_LL_ERROR + message:[NSString + stringWithFormat: + @"cannot setPushToStartToken on iOS < 17.2"]]; + } +#endif +} + +RCT_EXPORT_METHOD(removePushToStartToken : (NSString *)activityType) { +#if !TARGET_OS_MACCATALYST + NSError *err = nil; + if (@available(iOS 17.2, *)) { + [OneSignalLiveActivitiesManagerImpl removePushToStartToken:activityType + error:&err]; + if (err) { + [OneSignalLog + onesignalLog:ONE_S_LL_ERROR + message:[NSString + stringWithFormat:@"activityType must be the name of " + @"your ActivityAttributes struct"]]; } - #endif -} - -RCT_EXPORT_METHOD(startDefaultLiveActivity:(NSString *)activityId - withAttributes:(NSDictionary * _Nonnull)attributes - withContent:(NSDictionary * _Nonnull)content) { - #if !TARGET_OS_MACCATALYST - if (@available(iOS 16.1, *)) { - [OneSignalLiveActivitiesManagerImpl startDefault:activityId attributes:attributes content:content]; - } else { - [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"cannot startDefault on iOS < 16.1"]]; - } - #endif -} - -RCT_EXPORT_METHOD(setPrivacyConsentGiven:(BOOL)granted) { - dispatch_async(dispatch_get_main_queue(), ^{ - [OneSignal setConsentGiven:granted]; - }); -} - -RCT_EXPORT_METHOD(setPrivacyConsentRequired:(BOOL)required) { - [OneSignal setConsentRequired:required]; + } else { + [OneSignalLog + onesignalLog:ONE_S_LL_ERROR + message:[NSString + stringWithFormat: + @"cannot removePushToStartToken on iOS < 17.2"]]; + } +#endif +} + +RCT_EXPORT_METHOD(setupDefaultLiveActivity : (NSDictionary *_Nullable)options) { +#if !TARGET_OS_MACCATALYST + LiveActivitySetupOptions *laOptions = nil; + if (options != nil) { + laOptions = [LiveActivitySetupOptions alloc]; + [laOptions setEnablePushToStart:[options[@"enablePushToStart"] boolValue]]; + [laOptions + setEnablePushToUpdate:[options[@"enablePushToUpdate"] boolValue]]; + } + + if (@available(iOS 16.1, *)) { + [OneSignalLiveActivitiesManagerImpl setupDefaultWithOptions:laOptions]; + } else { + [OneSignalLog + onesignalLog:ONE_S_LL_ERROR + message:[NSString stringWithFormat: + @"cannot setupDefault on iOS < 16.1"]]; + } +#endif +} + +RCT_EXPORT_METHOD(startDefaultLiveActivity : ( + NSString *)activityId withAttributes : (NSDictionary *_Nonnull)attributes + withContent : (NSDictionary *_Nonnull)content) { +#if !TARGET_OS_MACCATALYST + if (@available(iOS 16.1, *)) { + [OneSignalLiveActivitiesManagerImpl startDefault:activityId + attributes:attributes + content:content]; + } else { + [OneSignalLog + onesignalLog:ONE_S_LL_ERROR + message:[NSString stringWithFormat: + @"cannot startDefault on iOS < 16.1"]]; + } +#endif +} + +RCT_EXPORT_METHOD(setPrivacyConsentGiven : (BOOL)granted) { + dispatch_async(dispatch_get_main_queue(), ^{ + [OneSignal setConsentGiven:granted]; + }); +} + +RCT_EXPORT_METHOD(setPrivacyConsentRequired : (BOOL)required) { + [OneSignal setConsentRequired:required]; } // OneSignal.Debug namespace methods -RCT_EXPORT_METHOD(setLogLevel:(int)logLevel) { - [OneSignal.Debug setLogLevel:logLevel]; +RCT_EXPORT_METHOD(setLogLevel : (int)logLevel) { + [OneSignal.Debug setLogLevel:logLevel]; } -RCT_EXPORT_METHOD(setAlertLevel:(int)logLevel) { - [OneSignal.Debug setAlertLevel:logLevel]; +RCT_EXPORT_METHOD(setAlertLevel : (int)logLevel) { + [OneSignal.Debug setAlertLevel:logLevel]; } // OneSignal.InAppMessages namespace methods -RCT_REMAP_METHOD(getPaused, - getPausedResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - resolve(@([OneSignal.InAppMessages paused])); +RCT_REMAP_METHOD(getPaused, + getPausedResolver : (RCTPromiseResolveBlock) + resolve rejecter : (RCTPromiseRejectBlock)reject) { + resolve(@([OneSignal.InAppMessages paused])); } -RCT_EXPORT_METHOD(paused:(BOOL)pause) { - [OneSignal.InAppMessages paused:pause]; +RCT_EXPORT_METHOD(paused : (BOOL)pause) { + [OneSignal.InAppMessages paused:pause]; } -RCT_EXPORT_METHOD(addTrigger:(NSString *)key withValue:(NSString *)value) { - [OneSignal.InAppMessages addTrigger:key withValue:value]; +RCT_EXPORT_METHOD(addTrigger : (NSString *)key withValue : (NSString *)value) { + [OneSignal.InAppMessages addTrigger:key withValue:value]; } -RCT_EXPORT_METHOD(addTriggers:(NSDictionary *)triggers) { - [OneSignal.InAppMessages addTriggers:triggers]; +RCT_EXPORT_METHOD(addTriggers : (NSDictionary *)triggers) { + [OneSignal.InAppMessages addTriggers:triggers]; } -RCT_EXPORT_METHOD(removeTrigger:(NSString *)key) { - [OneSignal.InAppMessages removeTrigger:key]; +RCT_EXPORT_METHOD(removeTrigger : (NSString *)key) { + [OneSignal.InAppMessages removeTrigger:key]; } -RCT_EXPORT_METHOD(removeTriggers:(NSArray *)keys) { - [OneSignal.InAppMessages removeTriggers:keys]; +RCT_EXPORT_METHOD(removeTriggers : (NSArray *)keys) { + [OneSignal.InAppMessages removeTriggers:keys]; } -RCT_EXPORT_METHOD(clearTriggers) { - [OneSignal.InAppMessages clearTriggers]; -} +RCT_EXPORT_METHOD(clearTriggers) { [OneSignal.InAppMessages clearTriggers]; } RCT_EXPORT_METHOD(addInAppMessageClickListener) { - if (!_hasAddedInAppMessageClickListener) { - [OneSignal.InAppMessages addClickListener: [RCTOneSignal sharedInstance]]; - _hasAddedInAppMessageClickListener = true; - } + if (!_hasAddedInAppMessageClickListener) { + [OneSignal.InAppMessages addClickListener:[RCTOneSignal sharedInstance]]; + _hasAddedInAppMessageClickListener = true; + } } RCT_EXPORT_METHOD(addInAppMessagesLifecycleListener) { - if (!_hasAddedInAppMessageLifecycleListener) { - [OneSignal.InAppMessages addLifecycleListener:[RCTOneSignal sharedInstance]]; - _hasAddedInAppMessageLifecycleListener = true; - } + if (!_hasAddedInAppMessageLifecycleListener) { + [OneSignal.InAppMessages + addLifecycleListener:[RCTOneSignal sharedInstance]]; + _hasAddedInAppMessageLifecycleListener = true; + } } // OneSignal.Location namespace methods RCT_REMAP_METHOD(isLocationShared, - isLocationSharedResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - resolve(@([OneSignal.Location isShared])); + isLocationSharedResolver : (RCTPromiseResolveBlock) + resolve rejecter : (RCTPromiseRejectBlock)reject) { + resolve(@([OneSignal.Location isShared])); } -RCT_EXPORT_METHOD(setLocationShared:(BOOL)shared) { - [OneSignal.Location setShared:shared]; +RCT_EXPORT_METHOD(setLocationShared : (BOOL)shared) { + [OneSignal.Location setShared:shared]; } RCT_EXPORT_METHOD(requestLocationPermission) { - [OneSignal.Location requestPermission]; + [OneSignal.Location requestPermission]; } // OneSignal.Notifications namespace methods -RCT_REMAP_METHOD(hasNotificationPermission, - hasNotificationPermissionResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - resolve(@([OneSignal.Notifications permission])); +RCT_REMAP_METHOD(hasNotificationPermission, + hasNotificationPermissionResolver : (RCTPromiseResolveBlock) + resolve rejecter : (RCTPromiseRejectBlock)reject) { + resolve(@([OneSignal.Notifications permission])); } -RCT_REMAP_METHOD(canRequestNotificationPermission, - canRequestNotificationPermissionResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - resolve(@([OneSignal.Notifications canRequestPermission])); +RCT_REMAP_METHOD( + canRequestNotificationPermission, + canRequestNotificationPermissionResolver : (RCTPromiseResolveBlock) + resolve rejecter : (RCTPromiseRejectBlock)reject) { + resolve(@([OneSignal.Notifications canRequestPermission])); } -RCT_REMAP_METHOD(requestNotificationPermission, - withFallBackSettings:fallbackToSettings - requestNotificationPermissionResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - [OneSignal.Notifications requestPermission:^(BOOL accepted) { - resolve(@(accepted)); - } fallbackToSettings:[fallbackToSettings boolValue]]; +RCT_REMAP_METHOD( + requestNotificationPermission, + withFallBackSettings : fallbackToSettings + requestNotificationPermissionResolver : (RCTPromiseResolveBlock) + resolve rejecter : (RCTPromiseRejectBlock)reject) { + [OneSignal.Notifications + requestPermission:^(BOOL accepted) { + resolve(@(accepted)); + } + fallbackToSettings:[fallbackToSettings boolValue]]; } -RCT_EXPORT_METHOD(registerForProvisionalAuthorization:(RCTResponseSenderBlock)callback) { - [OneSignal.Notifications registerForProvisionalAuthorization:^(BOOL accepted) { - callback(@[@(accepted)]); - }]; +RCT_EXPORT_METHOD(registerForProvisionalAuthorization : (RCTResponseSenderBlock) + callback) { + [OneSignal.Notifications + registerForProvisionalAuthorization:^(BOOL accepted) { + callback(@[ @(accepted) ]); + }]; } RCT_EXPORT_METHOD(addPermissionObserver) { - if (!_hasSetPermissionObserver) { - [OneSignal.Notifications addPermissionObserver:[RCTOneSignal sharedInstance]]; - _hasSetPermissionObserver = true; - } + if (!_hasSetPermissionObserver) { + [OneSignal.Notifications + addPermissionObserver:[RCTOneSignal sharedInstance]]; + _hasSetPermissionObserver = true; + } } RCT_EXPORT_METHOD(removePermissionObserver) { - if (_hasSetPermissionObserver) { - [OneSignal.Notifications removePermissionObserver:[RCTOneSignal sharedInstance]]; - _hasSetPermissionObserver = false; - } + if (_hasSetPermissionObserver) { + [OneSignal.Notifications + removePermissionObserver:[RCTOneSignal sharedInstance]]; + _hasSetPermissionObserver = false; + } } RCT_REMAP_METHOD(permissionNative, - getPermissionNativeResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - resolve(@([OneSignal.Notifications permissionNative])); + getPermissionNativeResolver : (RCTPromiseResolveBlock) + resolve rejecter : (RCTPromiseRejectBlock)reject) { + resolve(@([OneSignal.Notifications permissionNative])); } RCT_EXPORT_METHOD(addNotificationClickListener) { - if (!_hasAddedNotificationClickListener) { - [OneSignal.Notifications addClickListener:[RCTOneSignal sharedInstance]]; - _hasAddedNotificationClickListener = true; - } + if (!_hasAddedNotificationClickListener) { + [OneSignal.Notifications addClickListener:[RCTOneSignal sharedInstance]]; + _hasAddedNotificationClickListener = true; + } } RCT_EXPORT_METHOD(addNotificationForegroundLifecycleListener) { - if (!_hasAddedNotificationForegroundLifecycleListener) { - [OneSignal.Notifications addForegroundLifecycleListener:self]; - _hasAddedNotificationForegroundLifecycleListener = true; - } -} - -RCT_EXPORT_METHOD(onWillDisplayNotification:(OSNotificationWillDisplayEvent *)event){ - __weak RCTOneSignalEventEmitter *weakSelf = self; - RCTOneSignalEventEmitter *strongSelf = weakSelf; - if (!strongSelf) return; - - strongSelf->_notificationWillDisplayCache[event.notification.notificationId] = event; - [event preventDefault]; - [RCTOneSignalEventEmitter sendEventWithName:@"OneSignal-notificationWillDisplayInForeground" withBody:[event.notification jsonRepresentation]]; -} - -RCT_EXPORT_METHOD(preventDefault:(NSString *)notificationId){ - __weak RCTOneSignalEventEmitter *weakSelf = self; - RCTOneSignalEventEmitter *strongSelf = weakSelf; - OSNotificationWillDisplayEvent *event = _notificationWillDisplayCache[notificationId]; - if (!event) { - [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"OneSignal (objc): could not find notification will display event for notification with id: %@", notificationId]]; - return; - } - strongSelf->_preventDefaultCache[event.notification.notificationId] = event; - [event preventDefault]; -} - -RCT_EXPORT_METHOD(clearAllNotifications) { - [OneSignal.Notifications clearAll]; -} + if (!_hasAddedNotificationForegroundLifecycleListener) { + [OneSignal.Notifications addForegroundLifecycleListener:self]; + _hasAddedNotificationForegroundLifecycleListener = true; + } +} + +RCT_EXPORT_METHOD(onWillDisplayNotification : (OSNotificationWillDisplayEvent *) + event) { + __weak RCTOneSignalEventEmitter *weakSelf = self; + RCTOneSignalEventEmitter *strongSelf = weakSelf; + if (!strongSelf) + return; + + strongSelf->_notificationWillDisplayCache[event.notification.notificationId] = + event; + [event preventDefault]; + [RCTOneSignalEventEmitter + sendEventWithName:@"OneSignal-notificationWillDisplayInForeground" + withBody:[event.notification jsonRepresentation]]; +} + +RCT_EXPORT_METHOD(preventDefault : (NSString *)notificationId) { + __weak RCTOneSignalEventEmitter *weakSelf = self; + RCTOneSignalEventEmitter *strongSelf = weakSelf; + OSNotificationWillDisplayEvent *event = + _notificationWillDisplayCache[notificationId]; + if (!event) { + [OneSignalLog + onesignalLog:ONE_S_LL_ERROR + message:[NSString + stringWithFormat: + @"OneSignal (objc): could not find notification " + @"will display event for notification with id: %@", + notificationId]]; + return; + } + strongSelf->_preventDefaultCache[event.notification.notificationId] = event; + [event preventDefault]; +} + +RCT_EXPORT_METHOD(clearAllNotifications) { [OneSignal.Notifications clearAll]; } // OneSignal.Session namespace methods -RCT_EXPORT_METHOD(addOutcome:(NSString *)name) { - [OneSignal.Session addOutcome:name]; +RCT_EXPORT_METHOD(addOutcome : (NSString *)name) { + [OneSignal.Session addOutcome:name]; } -RCT_EXPORT_METHOD(addUniqueOutcome:(NSString *)name) { - [OneSignal.Session addUniqueOutcome:name]; +RCT_EXPORT_METHOD(addUniqueOutcome : (NSString *)name) { + [OneSignal.Session addUniqueOutcome:name]; } -RCT_EXPORT_METHOD(addOutcomeWithValue:(NSString *)name :(NSNumber * _Nonnull)value) { - [OneSignal.Session addOutcomeWithValue:name value:value]; +RCT_EXPORT_METHOD(addOutcomeWithValue : (NSString *)name : (NSNumber *_Nonnull) + value) { + [OneSignal.Session addOutcomeWithValue:name value:value]; } // OneSignal.User namespace methods RCT_EXPORT_METHOD(addUserStateObserver) { - if (!_hasSetUserStateObserver) { - [OneSignal.User addObserver:[RCTOneSignal sharedInstance]]; - _hasSetUserStateObserver = true; - } + if (!_hasSetUserStateObserver) { + [OneSignal.User addObserver:[RCTOneSignal sharedInstance]]; + _hasSetUserStateObserver = true; + } } RCT_EXPORT_METHOD(addPushSubscriptionObserver) { - if (!_hasSetSubscriptionObserver) { - [OneSignal.User.pushSubscription addObserver:[RCTOneSignal sharedInstance]]; - _hasSetSubscriptionObserver = true; - } + if (!_hasSetSubscriptionObserver) { + [OneSignal.User.pushSubscription addObserver:[RCTOneSignal sharedInstance]]; + _hasSetSubscriptionObserver = true; + } } RCT_EXPORT_METHOD(removePushSubscriptionObserver) { - if (_hasSetSubscriptionObserver) { - [OneSignal.User.pushSubscription removeObserver:[RCTOneSignal sharedInstance]]; - _hasSetSubscriptionObserver = false; - } + if (_hasSetSubscriptionObserver) { + [OneSignal.User.pushSubscription + removeObserver:[RCTOneSignal sharedInstance]]; + _hasSetSubscriptionObserver = false; + } } -RCT_EXPORT_METHOD(setLanguage:(NSString *)language) { - [OneSignal.User setLanguage:language]; +RCT_EXPORT_METHOD(setLanguage : (NSString *)language) { + [OneSignal.User setLanguage:language]; } -RCT_EXPORT_METHOD(addEmail:(NSString *)email) { - [OneSignal.User addEmail:email]; +RCT_EXPORT_METHOD(addEmail : (NSString *)email) { + [OneSignal.User addEmail:email]; } -RCT_EXPORT_METHOD(removeEmail:(NSString *)email) { - [OneSignal.User removeEmail:email]; +RCT_EXPORT_METHOD(removeEmail : (NSString *)email) { + [OneSignal.User removeEmail:email]; } -RCT_EXPORT_METHOD(addSms:(NSString *)smsNumber) { - [OneSignal.User addSms:smsNumber]; +RCT_EXPORT_METHOD(addSms : (NSString *)smsNumber) { + [OneSignal.User addSms:smsNumber]; } -RCT_EXPORT_METHOD(removeSms:(NSString *)smsNumber) { - [OneSignal.User removeSms:smsNumber]; +RCT_EXPORT_METHOD(removeSms : (NSString *)smsNumber) { + [OneSignal.User removeSms:smsNumber]; } -RCT_EXPORT_METHOD(addTag:(NSString *)key value:(id)value) { - [OneSignal.User addTagWithKey:key value:value]; +RCT_EXPORT_METHOD(addTag : (NSString *)key value : (id)value) { + [OneSignal.User addTagWithKey:key value:value]; } -RCT_EXPORT_METHOD(addTags:(NSDictionary *)tags) { - [OneSignal.User addTags:tags]; +RCT_EXPORT_METHOD(addTags : (NSDictionary *)tags) { + [OneSignal.User addTags:tags]; } -RCT_EXPORT_METHOD(removeTag:(NSString *)key) { - [OneSignal.User removeTag:key]; +RCT_EXPORT_METHOD(removeTag : (NSString *)key) { + [OneSignal.User removeTag:key]; } -RCT_EXPORT_METHOD(removeTags:(NSArray *)keys) { - [OneSignal.User removeTags:keys]; +RCT_EXPORT_METHOD(removeTags : (NSArray *)keys) { + [OneSignal.User removeTags:keys]; } -RCT_EXPORT_METHOD(getTags:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - NSDictionary *tags = [OneSignal.User getTags]; - resolve(tags); +RCT_EXPORT_METHOD(getTags : (RCTPromiseResolveBlock) + resolve rejecter : (RCTPromiseRejectBlock)reject) { + NSDictionary *tags = [OneSignal.User getTags]; + resolve(tags); } RCT_REMAP_METHOD(getOnesignalId, - getOnesignalIdResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - NSString *onesignalId = OneSignal.User.onesignalId; - - if (onesignalId == nil || [onesignalId length] == 0) { - resolve([NSNull null]); // Resolve with null if nil or empty - } else { - resolve(onesignalId); - } -} + getOnesignalIdResolver : (RCTPromiseResolveBlock) + resolve rejecter : (RCTPromiseRejectBlock)reject) { + NSString *onesignalId = OneSignal.User.onesignalId; -RCT_REMAP_METHOD(getExternalId, - getExternalIdResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - NSString *externalId = OneSignal.User.externalId; - - if (externalId == nil || [externalId length] == 0) { - resolve([NSNull null]); // Resolve with null if nil or empty - } else { - resolve(externalId); - } -} - -RCT_EXPORT_METHOD(addAlias:(NSString *)label :(NSString *)id) { - [OneSignal.User addAliasWithLabel:label id:id]; + if (onesignalId == nil || [onesignalId length] == 0) { + resolve([NSNull null]); // Resolve with null if nil or empty + } else { + resolve(onesignalId); + } } -RCT_EXPORT_METHOD(removeAlias:(NSString *)label) { - [OneSignal.User removeAlias:label]; -} - -RCT_EXPORT_METHOD(addAliases:(NSDictionary *)aliases) { - [OneSignal.User addAliases:aliases]; -} +RCT_REMAP_METHOD(getExternalId, + getExternalIdResolver : (RCTPromiseResolveBlock) + resolve rejecter : (RCTPromiseRejectBlock)reject) { + NSString *externalId = OneSignal.User.externalId; -RCT_EXPORT_METHOD(removeAliases:(NSArray *)labels) { - [OneSignal.User removeAliases:labels]; + if (externalId == nil || [externalId length] == 0) { + resolve([NSNull null]); // Resolve with null if nil or empty + } else { + resolve(externalId); + } } - -// OneSignal.User.pushSubscription namespace methods -RCT_REMAP_METHOD(getOptedIn, - getOptedInResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - resolve(@(OneSignal.User.pushSubscription.optedIn)); -} - -RCT_REMAP_METHOD(getPushSubscriptionId, - getPushSubscriptionIdResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - NSString *pushId = OneSignal.User.pushSubscription.id; - if (pushId && ![pushId isEqualToString:@""]) { - resolve(pushId); - } else { - resolve([NSNull null]); - } +RCT_EXPORT_METHOD(addAlias : (NSString *)label : (NSString *)id) { + [OneSignal.User addAliasWithLabel:label id:id]; } -RCT_REMAP_METHOD(getPushSubscriptionToken, - getPushSubscriptionTokenResolver:(RCTPromiseResolveBlock)resolve - rejecter:(RCTPromiseRejectBlock)reject) { - NSString *token = OneSignal.User.pushSubscription.token; - if (token && ![token isEqualToString:@""]) { - resolve(token); - } else { - resolve([NSNull null]); - } +RCT_EXPORT_METHOD(removeAlias : (NSString *)label) { + [OneSignal.User removeAlias:label]; } -RCT_EXPORT_METHOD(optIn) { - [OneSignal.User.pushSubscription optIn]; +RCT_EXPORT_METHOD(addAliases : (NSDictionary *)aliases) { + [OneSignal.User addAliases:aliases]; } -RCT_EXPORT_METHOD(optOut) { - [OneSignal.User.pushSubscription optOut]; +RCT_EXPORT_METHOD(removeAliases : (NSArray *)labels) { + [OneSignal.User removeAliases:labels]; } -RCT_EXPORT_METHOD(displayNotification:(NSString*)notificationId) { - OSNotificationWillDisplayEvent *event = _notificationWillDisplayCache[notificationId]; - if (!event) { - [OneSignalLog onesignalLog:ONE_S_LL_ERROR message:[NSString stringWithFormat:@"OneSignal (objc): could not find notification will display event for notification with id: %@", notificationId]]; - return; - } - dispatch_async(dispatch_get_main_queue(), ^{ - [event.notification display]; - }); - - [_preventDefaultCache removeObjectForKey:notificationId]; - [_notificationWillDisplayCache removeObjectForKey:notificationId]; +// OneSignal.User.pushSubscription namespace methods +RCT_REMAP_METHOD(getOptedIn, + getOptedInResolver : (RCTPromiseResolveBlock) + resolve rejecter : (RCTPromiseRejectBlock)reject) { + resolve(@(OneSignal.User.pushSubscription.optedIn)); +} + +RCT_REMAP_METHOD(getPushSubscriptionId, + getPushSubscriptionIdResolver : (RCTPromiseResolveBlock) + resolve rejecter : (RCTPromiseRejectBlock)reject) { + NSString *pushId = OneSignal.User.pushSubscription.id; + if (pushId && ![pushId isEqualToString:@""]) { + resolve(pushId); + } else { + resolve([NSNull null]); + } +} + +RCT_REMAP_METHOD(getPushSubscriptionToken, + getPushSubscriptionTokenResolver : (RCTPromiseResolveBlock) + resolve rejecter : (RCTPromiseRejectBlock)reject) { + NSString *token = OneSignal.User.pushSubscription.token; + if (token && ![token isEqualToString:@""]) { + resolve(token); + } else { + resolve([NSNull null]); + } +} + +RCT_EXPORT_METHOD(optIn) { [OneSignal.User.pushSubscription optIn]; } + +RCT_EXPORT_METHOD(optOut) { [OneSignal.User.pushSubscription optOut]; } + +RCT_EXPORT_METHOD(displayNotification : (NSString *)notificationId) { + OSNotificationWillDisplayEvent *event = + _notificationWillDisplayCache[notificationId]; + if (!event) { + [OneSignalLog + onesignalLog:ONE_S_LL_ERROR + message:[NSString + stringWithFormat: + @"OneSignal (objc): could not find notification " + @"will display event for notification with id: %@", + notificationId]]; + return; + } + dispatch_async(dispatch_get_main_queue(), ^{ + [event.notification display]; + }); + + [_preventDefaultCache removeObjectForKey:notificationId]; + [_notificationWillDisplayCache removeObjectForKey:notificationId]; } RCT_EXPORT_METHOD(initInAppMessageClickHandlerParams) { - // iOS Stub + // iOS Stub } @end diff --git a/ios/RCTOneSignal/RCTOneSignalExtensionService.h b/ios/RCTOneSignal/RCTOneSignalExtensionService.h index 3d11fa30..63d3f365 100644 --- a/ios/RCTOneSignal/RCTOneSignalExtensionService.h +++ b/ios/RCTOneSignal/RCTOneSignalExtensionService.h @@ -2,7 +2,17 @@ #import @interface RCTOneSignalExtensionService : NSObject -+ (void)serviceExtensionTimeWillExpireRequest:(UNNotificationRequest * _Nonnull)request withMutableNotificationContent:(UNMutableNotificationContent * _Nullable)content; -+ (void)didReceiveNotificationRequest:(UNNotificationRequest * _Nonnull)request withContent:(UNMutableNotificationContent * _Nullable)content; -+ (void)didReceiveNotificationRequest:(UNNotificationRequest * _Nonnull)request withContent:(UNMutableNotificationContent * _Nullable)content withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler; ++ (void)serviceExtensionTimeWillExpireRequest: + (UNNotificationRequest *_Nonnull)request + withMutableNotificationContent: + (UNMutableNotificationContent *_Nullable)content; ++ (void)didReceiveNotificationRequest:(UNNotificationRequest *_Nonnull)request + withContent: + (UNMutableNotificationContent *_Nullable)content; ++ (void)didReceiveNotificationRequest:(UNNotificationRequest *_Nonnull)request + withContent: + (UNMutableNotificationContent *_Nullable)content + withContentHandler: + (void (^)(UNNotificationContent *_Nonnull)) + contentHandler; @end diff --git a/ios/RCTOneSignal/RCTOneSignalExtensionService.m b/ios/RCTOneSignal/RCTOneSignalExtensionService.m index 37bcde2c..4024d5ff 100644 --- a/ios/RCTOneSignal/RCTOneSignalExtensionService.m +++ b/ios/RCTOneSignal/RCTOneSignalExtensionService.m @@ -1,20 +1,32 @@ #import - #import "RCTOneSignalExtensionService.h" @implementation RCTOneSignalExtensionService -//forwards OneSignal notification extension requests -+(void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContent:(UNMutableNotificationContent * _Nullable)content { - [OneSignal didReceiveNotificationExtensionRequest:request withMutableNotificationContent:content]; +// forwards OneSignal notification extension requests ++ (void)didReceiveNotificationRequest:(UNNotificationRequest *)request + withContent: + (UNMutableNotificationContent *_Nullable)content { + [OneSignal didReceiveNotificationExtensionRequest:request + withMutableNotificationContent:content]; } -+ (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContent:(UNMutableNotificationContent* _Nullable)content withContentHandler:(void (^)(UNNotificationContent *_Nonnull))contentHandler { - [OneSignal didReceiveNotificationExtensionRequest:request withMutableNotificationContent:content withContentHandler:contentHandler]; ++ (void)didReceiveNotificationRequest:(UNNotificationRequest *)request + withContent: + (UNMutableNotificationContent *_Nullable)content + withContentHandler: + (void (^)(UNNotificationContent *_Nonnull)) + contentHandler { + [OneSignal didReceiveNotificationExtensionRequest:request + withMutableNotificationContent:content + withContentHandler:contentHandler]; } -+(void)serviceExtensionTimeWillExpireRequest:(UNNotificationRequest *)request withMutableNotificationContent:(UNMutableNotificationContent * _Nullable)content { - [OneSignal serviceExtensionTimeWillExpireRequest:request withMutableNotificationContent:content]; ++ (void)serviceExtensionTimeWillExpireRequest:(UNNotificationRequest *)request + withMutableNotificationContent: + (UNMutableNotificationContent *_Nullable)content { + [OneSignal serviceExtensionTimeWillExpireRequest:request + withMutableNotificationContent:content]; } @end diff --git a/ios/RCTOneSignal/UIApplication+RCTOnesignal.m b/ios/RCTOneSignal/UIApplication+RCTOnesignal.m index 4ecca7c3..ba940794 100644 --- a/ios/RCTOneSignal/UIApplication+RCTOnesignal.m +++ b/ios/RCTOneSignal/UIApplication+RCTOnesignal.m @@ -2,63 +2,77 @@ #import @interface RCTOneSignal -+ (RCTOneSignal *) sharedInstance; -- (void)initialize:(nonnull NSString*)newAppId withLaunchOptions:(nullable NSDictionary*)launchOptions; -- (void)initOneSignal:(NSDictionary*)launchOptions; ++ (RCTOneSignal *)sharedInstance; +- (void)initialize:(nonnull NSString *)newAppId + withLaunchOptions:(nullable NSDictionary *)launchOptions; +- (void)initOneSignal:(NSDictionary *)launchOptions; @end -@implementation UIApplication(OneSignalReactNative) +@implementation UIApplication (OneSignalReactNative) /* - This UIApplication category ensures that OneSignal init() gets called at least one time + This UIApplication category ensures that OneSignal init() gets called at + least one time - If this did not occur, cold-start notifications would not trigger the React-Native 'opened' - event and other miscellaneous problems would occur. + If this did not occur, cold-start notifications would not trigger the + React-Native 'opened' event and other miscellaneous problems would occur. - First, we swizzle UIApplication's setDelegate method, to get notified when the app delegate - is assigned. Then we swizzle UIApplication's didFinishLaunchingWithOptions() method. When - this method gets called, it initializes the OneSignal SDK with a nil app ID. + First, we swizzle UIApplication's setDelegate method, to get notified when + the app delegate is assigned. Then we swizzle UIApplication's + didFinishLaunchingWithOptions() method. When this method gets called, it + initializes the OneSignal SDK with a nil app ID. */ // helper method to swizzle instance methods -static void injectSelector(Class newClass, SEL newSel, Class addToClass, SEL makeLikeSel) { - Method newMeth = class_getInstanceMethod(newClass, newSel); - IMP imp = method_getImplementation(newMeth); - const char* methodTypeEncoding = method_getTypeEncoding(newMeth); +static void injectSelector(Class newClass, SEL newSel, Class addToClass, + SEL makeLikeSel) { + Method newMeth = class_getInstanceMethod(newClass, newSel); + IMP imp = method_getImplementation(newMeth); + const char *methodTypeEncoding = method_getTypeEncoding(newMeth); - BOOL successful = class_addMethod(addToClass, makeLikeSel, imp, methodTypeEncoding); - if (!successful) { - class_addMethod(addToClass, newSel, imp, methodTypeEncoding); - newMeth = class_getInstanceMethod(addToClass, newSel); + BOOL successful = + class_addMethod(addToClass, makeLikeSel, imp, methodTypeEncoding); + if (!successful) { + class_addMethod(addToClass, newSel, imp, methodTypeEncoding); + newMeth = class_getInstanceMethod(addToClass, newSel); - Method orgMeth = class_getInstanceMethod(addToClass, makeLikeSel); + Method orgMeth = class_getInstanceMethod(addToClass, makeLikeSel); - method_exchangeImplementations(orgMeth, newMeth); - } + method_exchangeImplementations(orgMeth, newMeth); + } } + (void)load { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - method_exchangeImplementations(class_getInstanceMethod(self, @selector(setDelegate:)), class_getInstanceMethod(self, @selector(setOneSignalReactNativeDelegate:))); - }); + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + method_exchangeImplementations( + class_getInstanceMethod(self, @selector(setDelegate:)), + class_getInstanceMethod(self, + @selector(setOneSignalReactNativeDelegate:))); + }); } -- (void) setOneSignalReactNativeDelegate:(id)delegate { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - Class delegateClass = [delegate class]; - injectSelector(self.class, @selector(oneSignalApplication:didFinishLaunchingWithOptions:), - delegateClass, @selector(application:didFinishLaunchingWithOptions:)); - [self setOneSignalReactNativeDelegate:delegate]; - }); +- (void)setOneSignalReactNativeDelegate:(id)delegate { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + Class delegateClass = [delegate class]; + injectSelector(self.class, + @selector(oneSignalApplication: + didFinishLaunchingWithOptions:), + delegateClass, + @selector(application:didFinishLaunchingWithOptions:)); + [self setOneSignalReactNativeDelegate:delegate]; + }); } -- (BOOL)oneSignalApplication:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { - [[RCTOneSignal sharedInstance] initOneSignal:launchOptions]; - if ([self respondsToSelector:@selector(oneSignalApplication:didFinishLaunchingWithOptions:)]) - return [self oneSignalApplication:application didFinishLaunchingWithOptions:launchOptions]; - return YES; +- (BOOL)oneSignalApplication:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [[RCTOneSignal sharedInstance] initOneSignal:launchOptions]; + if ([self respondsToSelector:@selector(oneSignalApplication: + didFinishLaunchingWithOptions:)]) + return [self oneSignalApplication:application + didFinishLaunchingWithOptions:launchOptions]; + return YES; } @end diff --git a/package.json b/package.json index ca99c73b..83c4f78c 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,14 @@ "scripts": { "prepare": "bun run build", "build": "tsc --noEmit && vite build", - "lint": "oxlint src examples && prettier --check src examples", - "lint:fix": "oxlint src examples --fix && prettier --write src examples", + "format:spotless": "./examples/RNOneSignalTS/android/gradlew spotlessApply", + "format:prettier": "prettier --write \"**/*.{ts,tsx}\" --ignore-path .gitignore", + "format": "concurrently \"bun run format:spotless\" \"bun run format:prettier\"", + "format:check:spotless": "./examples/RNOneSignalTS/android/gradlew spotlessCheck", + "format:check:prettier": "prettier --check \"**/*.{ts,tsx}\" --ignore-path .gitignore", + "format:check": "concurrently \"bun run format:check:spotless\" \"bun run format:check:prettier\"", + "lint": "oxlint src examples && bun run format:check", + "lint:fix": "oxlint src examples --fix && bun run format", "test": "vitest", "test:coverage": "vitest run --coverage" }, @@ -25,6 +31,7 @@ "@types/invariant": "^2.2.37", "@types/react-native": "^0.73.0", "@vitest/coverage-v8": "4.0.8", + "concurrently": "^9.2.1", "oxlint": "^1.26.0", "prettier": "^3.6.2", "typescript": "^5.9.3",