@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.
- package/android/gradle.properties +4 -4
- package/android/src/main/java/com/urbanairship/reactnative/AirshipModule.kt +108 -164
- package/android/src/main/java/com/urbanairship/reactnative/ReactAutopilot.kt +26 -3
- package/android/src/main/java/com/urbanairship/reactnative/ReactMessageView.kt +71 -55
- package/android/src/main/java/com/urbanairship/reactnative/ReactNotificationProvider.kt +0 -5
- package/ios/AirshipReactNative.swift +84 -23
- package/ios/MessageWebViewWrapper.swift +6 -6
- package/ios/ProxyDataMigrator.swift +1 -0
- package/ios/RTNAirship.mm +2 -2
- package/package.json +1 -1
- package/react-native-airship.podspec +2 -3
|
@@ -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
|
-
|
|
37
|
-
|
|
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.
|
|
16
|
-
import com.urbanairship.
|
|
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
|
|
22
|
-
import
|
|
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
|
|
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?,
|
|
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.
|
|
44
|
+
notifyLoadError(message.id, ERROR_MESSAGE_LOAD_FAILED, false)
|
|
41
45
|
return
|
|
42
46
|
}
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
notifyLoadFinished(message.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
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
|
-
|
|
95
|
-
|
|
110
|
+
if (!isActive) {
|
|
111
|
+
return@launch
|
|
112
|
+
}
|
|
96
113
|
|
|
97
|
-
|
|
98
|
-
notifyLoadError(messageId, ERROR_MESSAGE_NOT_AVAILABLE, false)
|
|
99
|
-
return
|
|
100
|
-
}
|
|
114
|
+
notifyLoadStarted(messageId)
|
|
101
115
|
|
|
102
|
-
|
|
116
|
+
val messageResult = fetchMessage(messageId)
|
|
103
117
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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 = "
|
|
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
|
-
).
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
223
|
+
return try AirshipProxy.shared.channel.channelID ?? ""
|
|
211
224
|
}
|
|
212
225
|
|
|
213
226
|
@objc
|
|
214
227
|
func channelEditTagGroups(json: Any) throws {
|
|
215
|
-
try
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
695
|
-
|
|
696
|
-
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
139
|
+
return await Airship.messageCenter.inbox.message(forID: messageID)
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
public func close() {
|
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
|
|
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
|
@@ -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
|
+
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", "
|
|
26
|
-
|
|
25
|
+
s.dependency "AirshipFrameworkProxy", "12.1.1"
|
|
27
26
|
end
|