@ua/react-native-airship 20.2.0 → 21.0.1

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.
@@ -33,12 +33,17 @@ class ReactAutopilot : BaseAutopilot() {
33
33
  override fun onReady(context: Context, airship: UAirship) {
34
34
  ProxyLogger.info("Airship React Native version: %s, SDK version: %s", BuildConfig.AIRSHIP_MODULE_VERSION, UAirship.getVersion())
35
35
 
36
- scope.launch {
37
- EventEmitter.shared().pendingEventListener
36
+ val allowHeadlessJsTaskBeforeModule = isHeadlessJSTaskEnabledOnStart(context)
37
+ ProxyLogger.debug("ALLOW_HEADLESS_JS_TASK_BEFORE_MODULE: $allowHeadlessJsTaskBeforeModule")
38
+
39
+ if (allowHeadlessJsTaskBeforeModule) {
40
+ scope.launch {
41
+ EventEmitter.shared().pendingEventListener
38
42
  .filter { !it.type.isForeground() }
39
43
  .collect {
40
44
  AirshipHeadlessEventService.startService(context)
41
45
  }
46
+ }
42
47
  }
43
48
 
44
49
  scope.launch {
@@ -86,7 +91,24 @@ class ReactAutopilot : BaseAutopilot() {
86
91
  return null
87
92
  }
88
93
 
94
+ private fun isHeadlessJSTaskEnabledOnStart(context: Context): Boolean {
95
+ val ai: ApplicationInfo
96
+ try {
97
+ ai = context.packageManager.getApplicationInfo(context.packageName, PackageManager.GET_META_DATA)
98
+
99
+ if (ai.metaData == null) {
100
+ return true
101
+ }
102
+ } catch (e: PackageManager.NameNotFoundException) {
103
+ return true
104
+ }
105
+
106
+ return ai.metaData.getBoolean(HEADLESS_JS_TASK_ON_START_MANIFEST_KEY, true)
107
+ }
108
+
109
+
89
110
  companion object {
111
+ const val HEADLESS_JS_TASK_ON_START_MANIFEST_KEY = "com.urbanairship.reactnative.ALLOW_HEADLESS_JS_TASK_BEFORE_MODULE"
90
112
  const val EXTENDER_MANIFEST_KEY = "com.urbanairship.reactnative.AIRSHIP_EXTENDER"
91
113
  }
92
114
  }
@@ -97,4 +119,5 @@ internal class PendingEmbeddedUpdated(pending: List<AirshipEmbeddedInfo>) : Even
97
119
  override val body: JsonMap = jsonMapOf(
98
120
  "pending" to pending.map { jsonMapOf( "embeddedId" to it.embeddedId ) }
99
121
  )
100
- }
122
+ }
123
+
@@ -2,9 +2,8 @@
2
2
 
3
3
  package com.urbanairship.reactnative
4
4
 
5
+ import android.annotation.SuppressLint
5
6
  import android.content.Context
6
- import android.os.Handler
7
- import android.os.Looper
8
7
  import android.webkit.WebView
9
8
  import android.webkit.WebViewClient
10
9
  import android.widget.FrameLayout
@@ -12,37 +11,42 @@ import com.facebook.react.bridge.Arguments
12
11
  import com.facebook.react.bridge.LifecycleEventListener
13
12
  import com.facebook.react.bridge.ReactContext
14
13
  import com.facebook.react.bridge.WritableMap
15
- import com.facebook.react.uimanager.events.RCTEventEmitter
16
- import com.urbanairship.Cancelable
17
- import com.urbanairship.UAirship
18
- import com.urbanairship.messagecenter.Inbox.FetchMessagesCallback
14
+ import com.urbanairship.android.framework.proxy.ui.MessageWebView
15
+ import com.urbanairship.android.framework.proxy.ui.MessageWebViewClient
19
16
  import com.urbanairship.messagecenter.Message
20
17
  import com.urbanairship.messagecenter.MessageCenter
21
- import com.urbanairship.messagecenter.webkit.MessageWebView
22
- import com.urbanairship.messagecenter.webkit.MessageWebViewClient
23
-
18
+ import kotlinx.coroutines.CoroutineScope
19
+ import kotlinx.coroutines.Dispatchers
20
+ import kotlinx.coroutines.Job
21
+ import kotlinx.coroutines.SupervisorJob
22
+ import kotlinx.coroutines.delay
23
+ import kotlinx.coroutines.isActive
24
+ import kotlinx.coroutines.launch
25
+ import kotlinx.coroutines.plus
26
+
27
+ @SuppressLint("RestrictedApi")
24
28
  class ReactMessageView(context: Context) : FrameLayout(context), LifecycleEventListener {
25
29
 
26
30
  private var message: Message? = null
27
- private var fetchMessageRequest: Cancelable? = null
28
31
  private var webView: MessageWebView? = null
29
- private val loadHandler = Handler(Looper.getMainLooper())
32
+ private val scope: CoroutineScope = CoroutineScope(Dispatchers.Main.immediate) + SupervisorJob()
33
+ private var loadJob: Job? = null
30
34
 
31
35
  private val webViewClient: WebViewClient = object : MessageWebViewClient() {
32
36
 
33
37
  private var error: Int? = null
34
38
 
35
- override fun onPageFinished(view: WebView?, url: String?) {
39
+ override fun onPageFinished(view: WebView?, url: String?) {
36
40
  super.onPageFinished(view, url)
37
41
 
38
42
  message?.let { message ->
39
43
  error?.let {
40
- notifyLoadError(message.messageId, ERROR_MESSAGE_LOAD_FAILED, false)
44
+ notifyLoadError(message.id, ERROR_MESSAGE_LOAD_FAILED, false)
41
45
  return
42
46
  }
43
47
 
44
- message.markRead()
45
- notifyLoadFinished(message.messageId)
48
+ MessageCenter.shared().inbox.markMessagesRead(message.id)
49
+ notifyLoadFinished(message.id)
46
50
  }
47
51
  }
48
52
 
@@ -51,7 +55,7 @@ class ReactMessageView(context: Context) : FrameLayout(context), LifecycleEventL
51
55
 
52
56
  message?.let { message ->
53
57
  failingUrl?.let {
54
- if (it == message.messageBodyUrl) {
58
+ if (it == message.bodyUrl) {
55
59
  error = errorCode
56
60
  }
57
61
  }
@@ -60,12 +64,31 @@ class ReactMessageView(context: Context) : FrameLayout(context), LifecycleEventL
60
64
 
61
65
  public override fun onClose(webView: WebView) {
62
66
  message?.let {
63
- notifyClose(it.messageId)
67
+ notifyClose(it.id)
68
+ }
69
+ }
70
+ }
71
+
72
+ private suspend fun fetchMessage(messageId: String): FetchMessageResult {
73
+ var message = MessageCenter.shared().inbox.getMessage(messageId)
74
+
75
+ if (message == null) {
76
+ if (!MessageCenter.shared().inbox.fetchMessages()) {
77
+ return FetchMessageResult.Error(ERROR_FAILED_TO_FETCH_MESSAGE, true)
64
78
  }
79
+
80
+ message = MessageCenter.shared().inbox.getMessage(messageId)
81
+ }
82
+
83
+ return if (message == null || message.isExpired) {
84
+ FetchMessageResult.Error(ERROR_MESSAGE_NOT_AVAILABLE, false)
85
+ } else {
86
+ FetchMessageResult.Success(message)
65
87
  }
66
88
  }
67
89
 
68
90
  fun loadMessage(messageId: String) {
91
+ loadJob?.cancel()
69
92
  var delayLoading = false
70
93
 
71
94
  if (webView == null) {
@@ -75,50 +98,37 @@ class ReactMessageView(context: Context) : FrameLayout(context), LifecycleEventL
75
98
  delayLoading = true
76
99
  }
77
100
 
78
- fetchMessageRequest?.let {
79
- it.cancel()
80
- }
81
101
  message = null
82
102
 
83
- // Until ReactFeatureFlags.enableFabricPendingEventQueue is enabled by default, we need to avoid
84
- // sending events when the view is unmounted because the events are discarded otherwise
85
- if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED && delayLoading) {
86
- loadHandler.postDelayed({
87
- startLoading(messageId)
88
- }, 50)
89
- } else {
90
- startLoading(messageId)
91
- }
92
- }
103
+ loadJob = scope.launch {
104
+ // Until ReactFeatureFlags.enableFabricPendingEventQueue is enabled by default, we need to avoid
105
+ // sending events when the view is unmounted because the events are discarded otherwise
106
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED && delayLoading) {
107
+ delay(50)
108
+ }
93
109
 
94
- fun startLoading(messageId: String) {
95
- notifyLoadStarted(messageId)
110
+ if (!isActive) {
111
+ return@launch
112
+ }
96
113
 
97
- if (!(UAirship.isFlying() || UAirship.isTakingOff())) {
98
- notifyLoadError(messageId, ERROR_MESSAGE_NOT_AVAILABLE, false)
99
- return
100
- }
114
+ notifyLoadStarted(messageId)
101
115
 
102
- message = MessageCenter.shared().inbox.getMessage(messageId)
116
+ val messageResult = fetchMessage(messageId)
103
117
 
104
- if (message == null) {
105
- fetchMessageRequest = MessageCenter.shared().inbox.fetchMessages(FetchMessagesCallback { success ->
106
- message = MessageCenter.shared().inbox.getMessage(messageId)
107
- if (!success) {
108
- notifyLoadError(messageId, ERROR_FAILED_TO_FETCH_MESSAGE, true)
109
- return@FetchMessagesCallback
110
- } else if (message == null || message!!.isExpired) {
111
- notifyLoadError(messageId, ERROR_MESSAGE_NOT_AVAILABLE, false)
112
- return@FetchMessagesCallback
113
- }
114
- webView?.loadMessage(message!!)
115
- })
116
- } else {
117
- if (message!!.isExpired) {
118
- notifyLoadError(messageId, ERROR_MESSAGE_NOT_AVAILABLE, false)
119
- return
118
+ if (!isActive) {
119
+ return@launch
120
+ }
121
+
122
+ when (messageResult) {
123
+ is FetchMessageResult.Error -> {
124
+ notifyLoadError(messageId, messageResult.error, messageResult.isRetryable)
125
+ }
126
+
127
+ is FetchMessageResult.Success -> {
128
+ this@ReactMessageView.message = messageResult.message
129
+ webView?.loadMessage(messageResult.message)
130
+ }
120
131
  }
121
- webView?.loadMessage(message!!)
122
132
  }
123
133
  }
124
134
 
@@ -155,10 +165,12 @@ class ReactMessageView(context: Context) : FrameLayout(context), LifecycleEventL
155
165
 
156
166
  override fun onHostResume() {
157
167
  webView?.onResume()
168
+ webView?.resumeTimers()
158
169
  }
159
170
 
160
171
  override fun onHostPause() {
161
172
  webView?.onPause()
173
+ webView?.pauseTimers()
162
174
  }
163
175
 
164
176
  override fun onHostDestroy() {
@@ -166,7 +178,6 @@ class ReactMessageView(context: Context) : FrameLayout(context), LifecycleEventL
166
178
  }
167
179
 
168
180
  fun cleanup() {
169
- webView?.setWebViewClient(null)
170
181
  webView?.destroy()
171
182
  webView = null
172
183
  }
@@ -195,4 +206,9 @@ class ReactMessageView(context: Context) : FrameLayout(context), LifecycleEventL
195
206
  private const val ERROR_FAILED_TO_FETCH_MESSAGE = "FAILED_TO_FETCH_MESSAGE"
196
207
  private const val ERROR_MESSAGE_LOAD_FAILED = "MESSAGE_LOAD_FAILED"
197
208
  }
209
+ }
210
+
211
+ internal sealed class FetchMessageResult {
212
+ data class Success(val message: Message) : FetchMessageResult()
213
+ data class Error(val error: String, val isRetryable: Boolean) : FetchMessageResult()
198
214
  }
@@ -3,13 +3,8 @@
3
3
  package com.urbanairship.reactnative
4
4
 
5
5
  import android.content.Context
6
- import com.facebook.react.module.annotations.ReactModule
7
6
  import com.urbanairship.AirshipConfigOptions
8
7
  import com.urbanairship.android.framework.proxy.BaseNotificationProvider
9
- import com.urbanairship.push.notifications.NotificationArguments
10
- import com.urbanairship.push.notifications.NotificationResult
11
- import kotlinx.coroutines.MainScope
12
- import kotlinx.coroutines.runBlocking
13
8
 
14
9
  /**
15
10
  * React Native notification provider.
@@ -39,7 +39,7 @@ public class AirshipReactNative: NSObject {
39
39
  AirshipProxy.shared
40
40
  }
41
41
 
42
- public static let version: String = "20.2.0"
42
+ public static let version: String = "21.0.1"
43
43
 
44
44
  private let eventNotifier = EventNotifier()
45
45
 
@@ -48,7 +48,7 @@ public class AirshipReactNative: NSObject {
48
48
 
49
49
  @objc
50
50
  public func setNotifier(_ notifier: ((String, [String: Any]) -> Void)?) {
51
- self.serialQueue.enqueue {
51
+ self.serialQueue.enqueue { @MainActor in
52
52
  if let notifier = notifier {
53
53
  await self.eventNotifier.setNotifier {
54
54
  notifier(AirshipReactNative.pendingEventsEventName, [:])
@@ -135,7 +135,14 @@ public class AirshipReactNative: NSObject {
135
135
 
136
136
  return await AirshipProxyEventEmitter.shared.takePendingEvents(
137
137
  type: type
138
- ).map { $0.body }
138
+ ).compactMap {
139
+ do {
140
+ return try $0.body.unwrapped()
141
+ } catch {
142
+ AirshipLogger.error("Failed to unwrap event body \($0) \(error)")
143
+ return nil
144
+ }
145
+ }
139
146
  }
140
147
 
141
148
 
@@ -187,7 +194,13 @@ public extension AirshipReactNative {
187
194
 
188
195
  @objc
189
196
  func channelEditTags(json: Any) throws {
190
- try AirshipProxy.shared.channel.editTags(json: json)
197
+ let operations = try JSONDecoder().decode(
198
+ [TagOperation].self,
199
+ from: try AirshipJSONUtils.data(json)
200
+ )
201
+ try AirshipProxy.shared.channel.editTags(
202
+ operations: operations
203
+ )
191
204
  }
192
205
 
193
206
  @objc
@@ -197,27 +210,35 @@ public extension AirshipReactNative {
197
210
 
198
211
  @objc
199
212
  func channelGetTags() throws -> [String] {
200
- return try AirshipProxy.shared.channel.getTags()
213
+ return try AirshipProxy.shared.channel.tags
201
214
  }
202
215
 
203
216
  @objc
204
217
  func channelGetSubscriptionLists() async throws -> [String] {
205
- return try await AirshipProxy.shared.channel.getSubscriptionLists()
218
+ return try await AirshipProxy.shared.channel.fetchSubscriptionLists()
206
219
  }
207
220
 
208
221
  @objc
209
222
  func channelGetChannelIdOrEmpty() throws -> String {
210
- return try AirshipProxy.shared.channel.getChannelId() ?? ""
223
+ return try AirshipProxy.shared.channel.channelID ?? ""
211
224
  }
212
225
 
213
226
  @objc
214
227
  func channelEditTagGroups(json: Any) throws {
215
- try AirshipProxy.shared.channel.editTagGroups(json: json)
228
+ let operations = try JSONDecoder().decode(
229
+ [TagGroupOperation].self,
230
+ from: try AirshipJSONUtils.data(json)
231
+ )
232
+ try AirshipProxy.shared.channel.editTagGroups(operations: operations)
216
233
  }
217
234
 
218
235
  @objc
219
236
  func channelEditAttributes(json: Any) throws {
220
- try AirshipProxy.shared.channel.editAttributes(json: json)
237
+ let operations = try JSONDecoder().decode(
238
+ [AttributeOperation].self,
239
+ from: try AirshipJSONUtils.data(json)
240
+ )
241
+ try AirshipProxy.shared.channel.editAttributes(operations: operations)
221
242
  }
222
243
 
223
244
  @objc
@@ -254,11 +275,13 @@ public extension AirshipReactNative {
254
275
  }
255
276
 
256
277
  @objc
278
+ @MainActor
257
279
  func pushGetRegistrationTokenOrEmpty() throws -> String {
258
280
  return try AirshipProxy.shared.push.getRegistrationToken() ?? ""
259
281
  }
260
282
 
261
283
  @objc
284
+ @MainActor
262
285
  func pushSetNotificationOptions(
263
286
  names:[String]
264
287
  ) throws {
@@ -266,6 +289,7 @@ public extension AirshipReactNative {
266
289
  }
267
290
 
268
291
  @objc
292
+ @MainActor
269
293
  func pushSetForegroundPresentationOptions(
270
294
  names:[String]
271
295
  ) throws {
@@ -276,7 +300,7 @@ public extension AirshipReactNative {
276
300
 
277
301
  @objc
278
302
  func pushGetNotificationStatus() async throws -> [String: Any] {
279
- return try await AirshipProxy.shared.push.getNotificationStatus()
303
+ return try await AirshipProxy.shared.push.notificationStatus.unwrapped()
280
304
  }
281
305
 
282
306
  @objc
@@ -326,8 +350,8 @@ public extension AirshipReactNative {
326
350
  }
327
351
 
328
352
  @objc
329
- func pushGetActiveNotifications() async -> [[String: Any]] {
330
- return await AirshipProxy.shared.push.getActiveNotifications()
353
+ func pushGetActiveNotifications() async throws -> [[String: Any]] {
354
+ return try await AirshipProxy.shared.push.getActiveNotifications().map { try $0.unwrapped() }
331
355
  }
332
356
  }
333
357
 
@@ -394,7 +418,7 @@ public extension AirshipReactNative {
394
418
 
395
419
  @objc
396
420
  func contactGetNamedUserIdOrEmtpy() async throws -> String {
397
- return try await AirshipProxy.shared.contact.getNamedUser() ?? ""
421
+ return try await AirshipProxy.shared.contact.namedUserID ?? ""
398
422
  }
399
423
 
400
424
  @objc
@@ -404,17 +428,29 @@ public extension AirshipReactNative {
404
428
 
405
429
  @objc
406
430
  func contactEditTagGroups(json: Any) throws {
407
- try AirshipProxy.shared.contact.editTagGroups(json: json)
431
+ let operations = try JSONDecoder().decode(
432
+ [TagGroupOperation].self,
433
+ from: try AirshipJSONUtils.data(json)
434
+ )
435
+ try AirshipProxy.shared.contact.editTagGroups(operations: operations)
408
436
  }
409
437
 
410
438
  @objc
411
439
  func contactEditAttributes(json: Any) throws {
412
- try AirshipProxy.shared.contact.editAttributes(json: json)
440
+ let operations = try JSONDecoder().decode(
441
+ [AttributeOperation].self,
442
+ from: try AirshipJSONUtils.data(json)
443
+ )
444
+ try AirshipProxy.shared.contact.editAttributes(operations: operations)
413
445
  }
414
446
 
415
447
  @objc
416
448
  func contactEditSubscriptionLists(json: Any) throws {
417
- try AirshipProxy.shared.contact.editSubscriptionLists(json: json)
449
+ let operations = try JSONDecoder().decode(
450
+ [ScopedSubscriptionListOperation].self,
451
+ from: try AirshipJSONUtils.data(json)
452
+ )
453
+ try AirshipProxy.shared.contact.editSubscriptionLists(operations: operations)
418
454
  }
419
455
  }
420
456
 
@@ -438,7 +474,7 @@ public extension AirshipReactNative {
438
474
  @objc
439
475
  @MainActor
440
476
  func inAppSetDisplayInterval(milliseconds: Double) throws {
441
- try AirshipProxy.shared.inApp.setDisplayInterval(Int(milliseconds))
477
+ try AirshipProxy.shared.inApp.setDisplayInterval(milliseconds: Int(milliseconds))
442
478
  }
443
479
 
444
480
  @objc
@@ -470,7 +506,7 @@ public extension AirshipReactNative {
470
506
 
471
507
  @objc
472
508
  func localeGetLocale() throws -> String {
473
- return try AirshipProxy.shared.locale.getCurrentLocale()
509
+ return try AirshipProxy.shared.locale.currentLocale
474
510
  }
475
511
  }
476
512
 
@@ -479,12 +515,12 @@ public extension AirshipReactNative {
479
515
  public extension AirshipReactNative {
480
516
  @objc
481
517
  func messageCenterGetUnreadCount() async throws -> Double {
482
- return try await Double(AirshipProxy.shared.messageCenter.getUnreadCount())
518
+ return try await Double(AirshipProxy.shared.messageCenter.unreadCount)
483
519
  }
484
520
 
485
521
  @objc
486
522
  func messageCenterGetMessages() async throws -> Any {
487
- let messages = try await AirshipProxy.shared.messageCenter.getMessages()
523
+ let messages = try await AirshipProxy.shared.messageCenter.messages
488
524
  return try AirshipJSON.wrap(messages).unWrap() as Any
489
525
  }
490
526
 
@@ -528,6 +564,7 @@ public extension AirshipReactNative {
528
564
  }
529
565
 
530
566
  @objc
567
+ @MainActor
531
568
  func messageCenterSetAutoLaunchDefaultMessageCenter(autoLaunch: Bool) {
532
569
  AirshipProxy.shared.messageCenter.setAutoLaunchDefaultMessageCenter(autoLaunch)
533
570
  }
@@ -537,6 +574,7 @@ public extension AirshipReactNative {
537
574
  @objc
538
575
  public extension AirshipReactNative {
539
576
  @objc
577
+ @MainActor
540
578
  func preferenceCenterDisplay(preferenceCenterId: String) throws {
541
579
  try AirshipProxy.shared.preferenceCenter.displayPreferenceCenter(
542
580
  preferenceCenterID: preferenceCenterId
@@ -551,6 +589,7 @@ public extension AirshipReactNative {
551
589
  }
552
590
 
553
591
  @objc
592
+ @MainActor
554
593
  func preferenceCenterAutoLaunchDefaultPreferenceCenter(
555
594
  preferenceCenterId: String,
556
595
  autoLaunch: Bool
@@ -691,9 +730,21 @@ extension AirshipReactNative: AirshipProxyDelegate {
691
730
  }
692
731
 
693
732
  public func loadDefaultConfig() -> AirshipConfig {
694
- let config = AirshipConfig.default()
695
- config.requireInitialRemoteConfigEnabled = true
696
- return config
733
+ let path = Bundle.main.path(
734
+ forResource: "AirshipConfig",
735
+ ofType: "plist"
736
+ )
737
+
738
+ var config: AirshipConfig?
739
+ if let path = path, FileManager.default.fileExists(atPath: path) {
740
+ do {
741
+ config = try AirshipConfig.default()
742
+ } catch {
743
+ AirshipLogger.error("Failed to load config from plist: \(error)")
744
+ }
745
+ }
746
+
747
+ return config ?? AirshipConfig()
697
748
  }
698
749
 
699
750
  public func onAirshipReady() {
@@ -741,3 +792,13 @@ extension AirshipProxyEventType {
741
792
  return type
742
793
  }
743
794
  }
795
+
796
+
797
+ fileprivate extension Encodable {
798
+ func unwrapped<T>() throws -> T {
799
+ guard let value = try AirshipJSON.wrap(self).unWrap() as? T else {
800
+ throw AirshipErrors.error("Failed to unwrap codable")
801
+ }
802
+ return value
803
+ }
804
+ }
@@ -48,7 +48,7 @@ public class MessageWebViewWrapper: NSObject {
48
48
  }
49
49
 
50
50
 
51
- class _MessageWebViewWrapper: NSObject, UANavigationDelegate, NativeBridgeDelegate {
51
+ class _MessageWebViewWrapper: NSObject, AirshipWKNavigationDelegate, NativeBridgeDelegate {
52
52
 
53
53
  public weak var delegate: MessageWebViewWrapperDelegate? = nil
54
54
 
@@ -69,7 +69,7 @@ class _MessageWebViewWrapper: NSObject, UANavigationDelegate, NativeBridgeDelega
69
69
  self.webView.configuration.dataDetectorTypes = .all
70
70
 
71
71
  if #available(iOS 16.4, *) {
72
- self.webView.isInspectable = Airship.isFlying && Airship.config.isWebViewInspectionEnabled
72
+ self.webView.isInspectable = Airship.isFlying && Airship.config.airshipConfig.isWebViewInspectionEnabled
73
73
  }
74
74
  }
75
75
 
@@ -103,7 +103,7 @@ class _MessageWebViewWrapper: NSObject, UANavigationDelegate, NativeBridgeDelega
103
103
  self.delegate?.onMessageLoadFailed(messageID: messageID)
104
104
  }
105
105
 
106
- guard let message = message, let user = await MessageCenter.shared.inbox.user else {
106
+ guard let message = message, let user = await Airship.messageCenter.inbox.user else {
107
107
  if (!Task.isCancelled) {
108
108
  self.delegate?.onMessageGone(messageID: messageID)
109
109
  }
@@ -115,7 +115,7 @@ class _MessageWebViewWrapper: NSObject, UANavigationDelegate, NativeBridgeDelega
115
115
  user: user
116
116
  )
117
117
  self.nativeBridge.nativeBridgeExtensionDelegate = self.nativeBridgeExtension
118
- let auth = await MessageCenter.shared.inbox.user?.basicAuthString
118
+ let auth = await Airship.messageCenter.inbox.user?.basicAuthString
119
119
 
120
120
  var request = URLRequest(url: message.bodyURL)
121
121
  request.timeoutInterval = 60
@@ -130,13 +130,13 @@ class _MessageWebViewWrapper: NSObject, UANavigationDelegate, NativeBridgeDelega
130
130
  }
131
131
 
132
132
  private func getMessage(messageID: String) async throws -> MessageCenterMessage? {
133
- let message = await MessageCenter.shared.inbox.message(forID: messageID)
133
+ let message = await Airship.messageCenter.inbox.message(forID: messageID)
134
134
  if let message = message {
135
135
  return message
136
136
  }
137
137
 
138
138
  try await AirshipProxy.shared.messageCenter.refresh()
139
- return await MessageCenter.shared.inbox.message(forID: messageID)
139
+ return await Airship.messageCenter.inbox.message(forID: messageID)
140
140
  }
141
141
 
142
142
  public func close() {
@@ -27,6 +27,7 @@ struct ProxyDataMigrator {
27
27
  private let configKey = "com.urbanairship.react.airship_config"
28
28
 
29
29
 
30
+ @MainActor
30
31
  func migrateData(store: ProxyStore) {
31
32
  // Presentation options
32
33
  let optionsInt = defaults.object(
package/ios/RTNAirship.mm CHANGED
@@ -133,8 +133,8 @@ RCT_REMAP_METHOD(channelEnableChannelCreation,
133
133
  RCT_REMAP_METHOD(pushGetActiveNotifications,
134
134
  pushGetActiveNotifications:(RCTPromiseResolveBlock)resolve
135
135
  reject:(RCTPromiseRejectBlock)reject) {
136
- [AirshipReactNative.shared pushGetActiveNotificationsWithCompletionHandler:^(NSArray<NSDictionary<NSString *,id> *> *result) {
137
- resolve(result);
136
+ [AirshipReactNative.shared pushGetActiveNotificationsWithCompletionHandler:^(NSArray<NSDictionary<NSString *,id> *> *result, NSError *error) {
137
+ [self handleResult:result error:error resolve:resolve reject:reject];
138
138
  }];
139
139
  }
140
140
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ua/react-native-airship",
3
- "version": "20.2.0",
3
+ "version": "21.0.1",
4
4
  "description": "Airship plugin for React Native apps.",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
11
11
  s.license = package["license"]
12
12
  s.authors = package["author"]
13
13
 
14
- s.platforms = { :ios => "14.0" }
14
+ s.platforms = { :ios => "15.0" }
15
15
  s.source = { :git => "https://github.com/urbanairship/react-native-module.git", :tag => "#{s.version}" }
16
16
 
17
17
  s.source_files = "ios/**/*.{h,m,mm,swift}"
@@ -22,6 +22,5 @@ Pod::Spec.new do |s|
22
22
  s.dependency "React-Core"
23
23
  end
24
24
 
25
- s.dependency "AirshipFrameworkProxy", "11.2.1"
26
-
25
+ s.dependency "AirshipFrameworkProxy", "12.1.1"
27
26
  end