pushwoosh-react-native-plugin 6.1.60 → 6.1.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pushwoosh-react-native-plugin",
3
- "version": "6.1.60",
3
+ "version": "6.1.61",
4
4
  "description": "This plugin allows you to send and receive push notifications. Powered by Pushwoosh (www.pushwoosh.com).",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = "pushwoosh-react-native-plugin"
3
- s.version = "6.1.60"
3
+ s.version = "6.1.61"
4
4
  s.summary = "React Native Pushwoosh Push Notifications module"
5
5
  s.requires_arc = true
6
6
  s.author = 'Pushwoosh'
@@ -15,6 +15,6 @@ Pod::Spec.new do |s|
15
15
  s.static_framework = true
16
16
 
17
17
  s.dependency 'React'
18
- s.dependency 'PushwooshXCFramework', '7.2.5'
18
+ s.dependency 'PushwooshXCFramework', '7.2.6'
19
19
  s.dependency 'PushwooshInboxUIXCFramework'
20
20
  end
@@ -37,7 +37,7 @@ android {
37
37
  }
38
38
 
39
39
  ext {
40
- pushwoosh = "6.11.1"
40
+ pushwoosh = "6.12.0"
41
41
  }
42
42
 
43
43
  dependencies {
@@ -49,6 +49,9 @@ dependencies {
49
49
  implementation "com.pushwoosh:pushwoosh-badge:${pushwoosh}"
50
50
  implementation "com.pushwoosh:pushwoosh-inbox:${pushwoosh}"
51
51
  implementation "com.pushwoosh:pushwoosh-inbox-ui:${pushwoosh}"
52
+ // InboxActivity calls androidx.activity.EdgeToEdge, added in 1.8.0; inbox-ui itself
53
+ // resolves 1.6.0, so the inbox screen dies with ClassNotFoundException without this
54
+ implementation "androidx.activity:activity:1.8.0"
52
55
  implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22"
53
56
  implementation "com.google.firebase:firebase-messaging:23.1.0"
54
57
  }
@@ -70,6 +70,7 @@ static PWEmailsCompletion emailsCompletionHandler(NSUInteger addressCount, RCTRe
70
70
 
71
71
  static NSDictionary * gStartPushData = nil;
72
72
  static NSURL * gPushDeepLinkURL = nil; // Deep link URL for New Architecture support
73
+ static NSString * gEarlyHandledHash = nil; // Last push hash the cold-start delegate accepted, to avoid double handling
73
74
  static NSString * const kRegistrationSuccesEvent = @"PWRegistrationSuccess";
74
75
  static NSString * const kRegistrationErrorEvent = @"PWRegistrationError";
75
76
  static NSString * const kPushReceivedEvent = @"PWPushReceived";
@@ -99,6 +100,17 @@ static NSURL * pwplugin_deepLinkURLFromPushLink(id link) {
99
100
  return url;
100
101
  }
101
102
 
103
+ // Bridgeless hands a module an RCTBridgeProxy: an NSProxy that carries none of NSObject's KVC and
104
+ // turns an unknown selector into a logged no-op. object_getClass asks without messaging it.
105
+ static BOOL pwplugin_isRealBridge(id bridge) {
106
+ if (bridge == nil) {
107
+ return NO;
108
+ }
109
+
110
+ Class bridgeProxyClass = NSClassFromString(@"RCTBridgeProxy");
111
+ return bridgeProxyClass == nil || object_getClass(bridge) != bridgeProxyClass;
112
+ }
113
+
102
114
  @interface PushwooshPlugin (InnerPushwooshPlugin)
103
115
 
104
116
  - (void) application:(UIApplication *)application pwplugin_didRegisterWithDeviceToken:(NSData *)deviceToken;
@@ -167,6 +179,12 @@ RCT_EXPORT_MODULE(Pushwoosh);
167
179
  return dispatch_get_main_queue();
168
180
  }
169
181
 
182
+ // Overriding init makes React Native infer main queue setup on its own; saying so keeps that
183
+ // contract explicit, since the module claims the notification center delegate right away.
184
+ + (BOOL)requiresMainQueueSetup {
185
+ return YES;
186
+ }
187
+
170
188
  + (NSString *)getPluginImplementationInfoPlistKey {
171
189
  return [[NSBundle mainBundle] objectForInfoDictionaryKey:kPushwooshPluginImplementationInfoPlistKey];
172
190
  }
@@ -235,11 +253,18 @@ RCT_EXPORT_METHOD(init:(NSDictionary*)config success:(RCTResponseSenderBlock)suc
235
253
  if (gStartPushData) {
236
254
  NSURL *deepLink = pwplugin_deepLinkURLFromPushLink(gStartPushData[@"l"]);
237
255
 
238
- //get deeplink from the payload and write it to the launchOptions for proper RCTLinking behavior
239
256
  if (deepLink) {
240
- NSMutableDictionary *launchOptions = self.bridge.launchOptions.mutableCopy;
241
- launchOptions[UIApplicationLaunchOptionsURLKey] = deepLink;
242
- [self.bridge setValue:launchOptions forKey:@"launchOptions"];
257
+ if (!gPushDeepLinkURL) {
258
+ gPushDeepLinkURL = deepLink;
259
+ }
260
+
261
+ // Writing the link into launchOptions is what makes RCTLinking report it, but only a
262
+ // real bridge accepts the write. Bridgeless reads it from the swizzled getInitialURL.
263
+ if (pwplugin_isRealBridge(self.bridge)) {
264
+ NSMutableDictionary *launchOptions = self.bridge.launchOptions.mutableCopy;
265
+ launchOptions[UIApplicationLaunchOptionsURLKey] = deepLink;
266
+ [self.bridge setValue:launchOptions forKey:@"launchOptions"];
267
+ }
243
268
  }
244
269
 
245
270
  [self sendJSEvent:kPushReceivedJSEvent withArgs:gStartPushData];
@@ -1000,9 +1025,15 @@ RCT_EXPORT_METHOD(getRichMediaType:(RCTResponseSenderBlock)callback) {
1000
1025
 
1001
1026
  #pragma mark - RCTEventEmitter
1002
1027
 
1028
+ // RCTEventEmitter withholds events until JS subscribes through NativeEventEmitter, which is what
1029
+ // raises its listener count. The plugin's public API is DeviceEventEmitter, which never raises it,
1030
+ // so observation stays off and every event goes out.
1031
+ - (instancetype)init {
1032
+ return [super initWithDisabledObservation];
1033
+ }
1034
+
1003
1035
  - (void)sendJSEvent:(NSString*)event withArgs:(NSDictionary*)args {
1004
- // [self sendEventWithName:event body:args];
1005
- [self.bridge.eventDispatcher sendDeviceEventWithName:event body:args];
1036
+ [self sendEventWithName:event body:args];
1006
1037
  }
1007
1038
 
1008
1039
  - (NSArray<NSString *> *)supportedEvents {
@@ -1053,17 +1084,45 @@ API_AVAILABLE(ios(10.0))
1053
1084
  @property (nonatomic, weak) id<UNUserNotificationCenterDelegate> originalDelegate;
1054
1085
  @end
1055
1086
 
1087
+ // PLUGIN_NOTIFICATION_HANDLER suppresses the native delegate, and the plugin's own delegate is
1088
+ // installed in JS init — too late for a cold start, so nobody accepts the launch push. Both early
1089
+ // hooks below call this; the push hash keeps the second one from repeating it.
1090
+ static void pwplugin_acceptColdStartPushOnce(NSDictionary *userInfo) {
1091
+ if (![userInfo isKindOfClass:[NSDictionary class]]) {
1092
+ return;
1093
+ }
1094
+ if (![[[NSBundle mainBundle] objectForInfoDictionaryKey:kPushwooshPluginImplementationInfoPlistKey] boolValue]) {
1095
+ return;
1096
+ }
1097
+ if (![PWMessage isPushwooshMessage:userInfo]) {
1098
+ return;
1099
+ }
1100
+
1101
+ NSString *hash = userInfo[@"p"];
1102
+ if ([hash isKindOfClass:[NSString class]]) {
1103
+ if ([gEarlyHandledHash isEqualToString:hash]) {
1104
+ return;
1105
+ }
1106
+ gEarlyHandledHash = hash;
1107
+ }
1108
+
1109
+ [[PushNotificationManager pushManager] handlePushAccepted:userInfo onStart:YES];
1110
+ }
1111
+
1056
1112
  @implementation PWEarlyNotificationDelegate
1057
1113
 
1058
1114
  - (void)userNotificationCenter:(UNUserNotificationCenter *)center
1059
1115
  didReceiveNotificationResponse:(UNNotificationResponse *)response
1060
1116
  withCompletionHandler:(void (^)(void))completionHandler API_AVAILABLE(ios(10.0)) {
1061
- // Capture deep link from push notification on cold start
1062
1117
  if ([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
1063
1118
  NSDictionary *userInfo = response.notification.request.content.userInfo;
1064
- NSURL *deepLink = pwplugin_deepLinkURLFromPushLink(userInfo[@"l"]);
1065
- if (deepLink) {
1066
- gPushDeepLinkURL = deepLink;
1119
+ NSURL *appSchemeDeepLink = pwplugin_deepLinkURLFromPushLink(userInfo[@"l"]);
1120
+
1121
+ if (appSchemeDeepLink) {
1122
+ // Routing it through the SDK too would deliver the deep link twice.
1123
+ gPushDeepLinkURL = appSchemeDeepLink;
1124
+ } else {
1125
+ pwplugin_acceptColdStartPushOnce(userInfo);
1067
1126
  }
1068
1127
  }
1069
1128
 
@@ -1123,8 +1182,12 @@ static PWEarlyNotificationDelegate *gEarlyDelegate = nil;
1123
1182
  NSDictionary *remoteNotification = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
1124
1183
  if (remoteNotification) {
1125
1184
  NSURL *deepLink = pwplugin_deepLinkURLFromPushLink(remoteNotification[@"l"]);
1126
- if (deepLink && !gPushDeepLinkURL) {
1127
- gPushDeepLinkURL = deepLink;
1185
+ if (deepLink) {
1186
+ if (!gPushDeepLinkURL) {
1187
+ gPushDeepLinkURL = deepLink;
1188
+ }
1189
+ } else {
1190
+ pwplugin_acceptColdStartPushOnce(remoteNotification);
1128
1191
  }
1129
1192
  }
1130
1193
  }];