diff --git a/AirshipFrameworkProxy.podspec b/AirshipFrameworkProxy.podspec index a6c9b57..c81a34c 100644 --- a/AirshipFrameworkProxy.podspec +++ b/AirshipFrameworkProxy.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| - s.version = "11.2.2" + s.version = "12.0.0" s.name = "AirshipFrameworkProxy" s.summary = "Airship iOS mobile framework proxy" s.documentation_url = "https://docs.airship.com/platform/mobile" @@ -11,11 +11,11 @@ Pod::Spec.new do |s| s.source = { :git => "/~https://github.com/urbanairship/airship-mobile-framework-proxy.git", :tag => s.version.to_s } s.module_name = "AirshipFrameworkProxy" - s.ios.deployment_target = "14.0" + s.ios.deployment_target = "15.0" s.requires_arc = true s.swift_version = "5.0" s.source_files = "ios/AirshipFrameworkProxy/**/*.{h,m,swift}" - s.dependency 'Airship', "18.14.2" + s.dependency 'Airship', "19.0.0" s.source_files = 'ios/AirshipFrameworkProxyLoader/**/*.{swift,h,m,c,cc,mm,cpp}', 'ios/AirshipFrameworkProxy/**/*.{swift,h,m,c,cc,mm,cpp}' end diff --git a/Package.resolved b/Package.resolved index 85ab830..8d99090 100644 --- a/Package.resolved +++ b/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "/~https://github.com/urbanairship/ios-library.git", "state" : { - "revision" : "89003c30ec77ef5d8419e6725d1c673d64429825", - "version" : "18.14.2" + "revision" : "03baf0f2e1dac61ac1fb676d9b3a6d540d2f144f", + "version" : "19.0.0" } } ], diff --git a/Package.swift b/Package.swift index fe9ef9e..1bbe9ec 100644 --- a/Package.swift +++ b/Package.swift @@ -7,7 +7,7 @@ import PackageDescription let package = Package( name: "AirshipFrameworkProxy", defaultLocalization: "en", - platforms: [.macOS(.v10_15), .iOS(.v14), .tvOS(.v14), .visionOS(.v1)], + platforms: [.macOS(.v10_15), .iOS(.v15), .tvOS(.v18), .visionOS(.v1)], products: [ .library( name: "AirshipFrameworkProxy", @@ -15,7 +15,7 @@ let package = Package( ) ], dependencies: [ - .package(url: "/~https://github.com/urbanairship/ios-library.git", from: "18.14.2") + .package(url: "/~https://github.com/urbanairship/ios-library.git", from: "19.0.0") ], targets: [ .target( diff --git a/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/AirshipListener.kt b/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/AirshipListener.kt index 6fbe2db..ee277f4 100644 --- a/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/AirshipListener.kt +++ b/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/AirshipListener.kt @@ -22,6 +22,10 @@ import com.urbanairship.push.NotificationListener import com.urbanairship.push.PushListener import com.urbanairship.push.PushMessage import com.urbanairship.push.PushTokenListener +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.launch internal class AirshipListener( private val proxyStore: ProxyStore, @@ -36,6 +40,7 @@ internal class AirshipListener( AirshipChannelListener, InboxListener { + private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob()) private val isAppForegrounded: Boolean get() { return GlobalActivityMonitor.shared(UAirship.getApplicationContext()).isAppForegrounded @@ -119,13 +124,16 @@ internal class AirshipListener( } override fun onInboxUpdated() { - eventEmitter.addEvent( - MessageCenterUpdatedEvent( - MessageCenter.shared().inbox.unreadCount, - MessageCenter.shared().inbox.count - ), - replacePending = true - ) + scope.launch { + eventEmitter.addEvent( + MessageCenterUpdatedEvent( + MessageCenter.shared().inbox.getUnreadCount(), + MessageCenter.shared().inbox.getCount() + ), + replacePending = true + ) + } + } } diff --git a/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/CustomMessageActivity.kt b/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/CustomMessageActivity.kt index 5407edb..206f406 100644 --- a/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/CustomMessageActivity.kt +++ b/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/CustomMessageActivity.kt @@ -5,7 +5,7 @@ package com.urbanairship.android.framework.proxy import android.os.Bundle import androidx.lifecycle.lifecycleScope import com.urbanairship.android.framework.proxy.proxies.AirshipProxy -import com.urbanairship.messagecenter.MessageActivity +import com.urbanairship.messagecenter.ui.MessageActivity import kotlinx.coroutines.launch public class CustomMessageActivity : MessageActivity() { @@ -21,4 +21,4 @@ public class CustomMessageActivity : MessageActivity() { } } } -} \ No newline at end of file +} diff --git a/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/MessageCenterMessage.kt b/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/MessageCenterMessage.kt index 0b04e69..42f0eb3 100644 --- a/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/MessageCenterMessage.kt +++ b/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/MessageCenterMessage.kt @@ -11,18 +11,18 @@ public data class MessageCenterMessage( val sentDate: Long, val listIconUrl: String?, val isRead: Boolean, - val extras: Map, + val extras: Map, val expirationDate: Long? ) : JsonSerializable { internal constructor(message: Message) : this( title = message.title, - id = message.messageId, - sentDate = message.sentDateMS, + id = message.id, + sentDate = message.sentDate.time, listIconUrl = message.listIconUrl, isRead = message.isRead, - extras = message.extrasMap, - expirationDate = message.expirationDateMS + extras = message.extras ?: emptyMap(), + expirationDate = message.expirationDate?.time ) override fun toJsonValue(): JsonValue = JsonMap.newBuilder() @@ -35,4 +35,4 @@ public data class MessageCenterMessage( .putOpt("expirationDate", expirationDate) .build() .toJsonValue() -} \ No newline at end of file +} diff --git a/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/proxies/MessageCenterProxy.kt b/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/proxies/MessageCenterProxy.kt index 1cdf966..14df2bd 100644 --- a/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/proxies/MessageCenterProxy.kt +++ b/android/airship-framework-proxy/src/main/java/com/urbanairship/android/framework/proxy/proxies/MessageCenterProxy.kt @@ -53,7 +53,7 @@ public class MessageCenterProxy internal constructor( messageId?.let { intent.setData(Uri.fromParts("message", it, null as String?)) } - + try { context.startActivity(intent) } catch(exception: Exception) { @@ -68,24 +68,23 @@ public class MessageCenterProxy internal constructor( } } - public fun getMessages(): List { - return messageCenterProvider().inbox.messages.map { MessageCenterMessage(it) } + public suspend fun getMessages(): List { + return messageCenterProvider().inbox.getMessages().map { MessageCenterMessage(it) } } - public fun getMessage(messageId: String): MessageCenterMessage { + public suspend fun getMessage(messageId: String): MessageCenterMessage { return MessageCenterMessage( requireNotNull(messageCenterProvider().inbox.getMessage(messageId)) ) } public fun deleteMessage(messageId: String) { - requireNotNull(messageCenterProvider().inbox.getMessage(messageId)) - .delete() + messageCenterProvider().inbox.deleteMessages(messageId) } - public fun markMessageRead(messageId: String) { - requireNotNull(messageCenterProvider().inbox.getMessage(messageId)) - .markRead() + + public suspend fun markMessageRead(messageId: String) { + messageCenterProvider().inbox.markMessagesRead(messageId) } public fun refreshInbox(): PendingResult { @@ -96,8 +95,8 @@ public class MessageCenterProxy internal constructor( return pendingResult } - public fun getUnreadMessagesCount(): Int { - return messageCenterProvider().inbox.unreadCount + public suspend fun getUnreadMessagesCount(): Int { + return messageCenterProvider().inbox.getUnreadCount() } public fun setAutoLaunchDefaultMessageCenter(enabled: Boolean) { diff --git a/android/gradle/libs.versions.toml b/android/gradle/libs.versions.toml index fd235b7..ac7da88 100644 --- a/android/gradle/libs.versions.toml +++ b/android/gradle/libs.versions.toml @@ -1,8 +1,8 @@ [versions] # Airship -airshipProxy = '11.2.2' -airship = '18.6.0' +airshipProxy = '12.0.0' +airship = '19.0.0' # Gradle plugins androidGradlePlugin = '8.3.2' @@ -17,22 +17,22 @@ ktlint = '0.45.2' # Dependencies # Kotlin -kotlin = '1.9.23' -kotlinx-coroutines = '1.7.3' +kotlin = '1.9.24' +kotlinx-coroutines = '1.8.1' # Androidx -androidx-annotation = '1.8.0' +androidx-annotation = '1.9.1' # Test google-truth = '1.1.3' junit = '4.13.2' mockk = '1.12.5' robolectric = '4.11.1' -androidx-test-core = '1.6.0' -androidx-test-espresso = '3.6.0' -androidx-test-junit = '1.2.0' -androidx-test-rules = '1.6.0' -androidx-test-runner = '1.6.0' +androidx-test-core = '1.6.1' +androidx-test-espresso = '3.6.1' +androidx-test-junit = '1.2.1' +androidx-test-rules = '1.6.1' +androidx-test-runner = '1.6.2' androidx-test-truth = '1.6.0' [plugins] diff --git a/ios/AirshipFrameworkProxy/AirshipDelegate.swift b/ios/AirshipFrameworkProxy/AirshipDelegate.swift index 931e5f3..6b6b1b9 100644 --- a/ios/AirshipFrameworkProxy/AirshipDelegate.swift +++ b/ios/AirshipFrameworkProxy/AirshipDelegate.swift @@ -11,7 +11,8 @@ import AirshipPreferenceCenter import AirshipAutomation #endif -class AirshipDelegate: NSObject { +@MainActor +final class AirshipDelegate { let proxyStore: ProxyStore let eventEmitter: AirshipProxyEventEmitter @@ -22,15 +23,14 @@ class AirshipDelegate: NSObject { ) { self.proxyStore = proxyStore self.eventEmitter = eventEmitter - super.init() } func messageCenterInboxUpdated() { Task { await self.eventEmitter.addEvent( MessageCenterUpdatedEvent( - messageCount: await MessageCenter.shared.inbox.messages.count, - unreadCount: await MessageCenter.shared.inbox.unreadCount + messageCount: await Airship.messageCenter.inbox.messages.count, + unreadCount: await Airship.messageCenter.inbox.unreadCount ), replacePending: true ) @@ -59,99 +59,55 @@ extension AirshipDelegate: PushNotificationDelegate { AirshipPluginForwardDelegates.shared.pushNotificationDelegate } - func receivedNotificationResponse( - _ notificationResponse: UNNotificationResponse, - completionHandler: @escaping () -> Void - ) { - Task { @MainActor in - if (notificationResponse.actionIdentifier != UNNotificationDismissActionIdentifier) { - await self.eventEmitter.addEvent( - NotificationResponseEvent( - response: notificationResponse - ) - ) - } - - guard - let forward = forwardPushDelegate?.receivedNotificationResponse - else { - completionHandler() - return - } - forward(notificationResponse, completionHandler) - } + @MainActor + func receivedForegroundNotification(_ userInfo: [AnyHashable : Any]) async { + await self.eventEmitter.addEvent( + PushReceivedEvent( + userInfo: userInfo, + isForeground: true + ) + ) + + await forwardPushDelegate?.receivedForegroundNotification(userInfo) } - func receivedBackgroundNotification( - _ userInfo: [AnyHashable : Any], - completionHandler: @escaping (UIBackgroundFetchResult - ) -> Void) { - Task { @MainActor in - await self.eventEmitter.addEvent( - PushReceivedEvent( - userInfo: userInfo, - isForeground: false - ) + @MainActor + func receivedBackgroundNotification(_ userInfo: [AnyHashable : Any]) async -> UIBackgroundFetchResult { + await self.eventEmitter.addEvent( + PushReceivedEvent( + userInfo: userInfo, + isForeground: false ) + ) - guard - let forward = forwardPushDelegate?.receivedBackgroundNotification - else { - completionHandler(.noData) - return - } - forward(userInfo, completionHandler) - } + return await forwardPushDelegate?.receivedBackgroundNotification(userInfo) ?? .noData } - func receivedForegroundNotification( - _ userInfo: [AnyHashable : Any], - completionHandler: @escaping () -> Void - ) { - Task { @MainActor in + @MainActor + func receivedNotificationResponse(_ notificationResponse: UNNotificationResponse) async { + if (notificationResponse.actionIdentifier != UNNotificationDismissActionIdentifier) { await self.eventEmitter.addEvent( - PushReceivedEvent( - userInfo: userInfo, - isForeground: true + NotificationResponseEvent( + response: notificationResponse ) ) - - guard - let forward = forwardPushDelegate?.receivedForegroundNotification - else { - completionHandler() - return - } - forward(userInfo, completionHandler) } - } - func extendPresentationOptions( - _ options: UNNotificationPresentationOptions, - notification: UNNotification, - completionHandler: @escaping (UNNotificationPresentationOptions) -> Void - ) { - Task { @MainActor in - guard - let forward = forwardPushDelegate?.extendPresentationOptions - else { - let overrides = await AirshipProxy.shared.push.presentationOptions( - notification: notification - ) - completionHandler(overrides ?? options) - return - } + await forwardPushDelegate?.receivedNotificationResponse(notificationResponse) + } - forward(options, notification, completionHandler) + @MainActor + func extendPresentationOptions(_ options: UNNotificationPresentationOptions, notification: UNNotification) async -> UNNotificationPresentationOptions { + guard + let forward = forwardPushDelegate?.extendPresentationOptions + else { + let overrides = await AirshipProxy.shared.push.presentationOptions( + notification: notification + ) + return overrides ?? options } - } - @preconcurrency @MainActor - func extend( - _ options: UNNotificationPresentationOptions, - notification: UNNotification - ) -> UNNotificationPresentationOptions { - return forwardPushDelegate?.extend?(options, notification: notification) ?? options + return await forward(options, notification) } } @@ -162,40 +118,39 @@ extension AirshipDelegate: RegistrationDelegate { AirshipPluginForwardDelegates.shared.registrationDelegate } - @preconcurrency @MainActor - func apnsRegistrationSucceeded(withDeviceToken deviceToken: Data) { + nonisolated func apnsRegistrationSucceeded(withDeviceToken deviceToken: Data) { let token = AirshipUtils.deviceTokenStringFromDeviceToken(deviceToken) - Task { + Task { @MainActor in await self.eventEmitter.addEvent( PushTokenReceivedEvent( pushToken: token ), replacePending: true ) - } - forwardRegistrationDelegate?.apnsRegistrationSucceeded?(withDeviceToken: deviceToken) + forwardRegistrationDelegate?.apnsRegistrationSucceeded(withDeviceToken: deviceToken) + } } - @preconcurrency @MainActor - func apnsRegistrationFailedWithError(_ error: Error) { - forwardRegistrationDelegate?.apnsRegistrationFailedWithError?(error) + nonisolated func apnsRegistrationFailedWithError(_ error: Error) { + Task { @MainActor in + forwardRegistrationDelegate?.apnsRegistrationFailedWithError(error) + } } - @preconcurrency @MainActor - func notificationAuthorizedSettingsDidChange( - _ authorizedSettings: UAAuthorizedNotificationSettings + nonisolated func notificationAuthorizedSettingsDidChange( + _ authorizedSettings: AirshipAuthorizedNotificationSettings ) { - Task { + Task { @MainActor in await self.eventEmitter.addEvent( AuthorizedNotificationSettingsChangedEvent( authorizedSettings: authorizedSettings ), replacePending: true ) - } - forwardRegistrationDelegate?.notificationAuthorizedSettingsDidChange?(authorizedSettings) + forwardRegistrationDelegate?.notificationAuthorizedSettingsDidChange(authorizedSettings) + } } } diff --git a/ios/AirshipFrameworkProxy/AirshipExtensions.swift b/ios/AirshipFrameworkProxy/AirshipExtensions.swift index bd0145c..ae7e582 100644 --- a/ios/AirshipFrameworkProxy/AirshipExtensions.swift +++ b/ios/AirshipFrameworkProxy/AirshipExtensions.swift @@ -11,7 +11,7 @@ import AirshipPreferenceCenter #endif -extension UAAuthorizationStatus { +extension UNAuthorizationStatus { var name: String { get throws { switch (self) { @@ -34,23 +34,23 @@ extension UAAuthorizationStatus { } } -extension UAAuthorizedNotificationSettings { - private static let nameMap: [String: UAAuthorizedNotificationSettings] = [ - "alert": UAAuthorizedNotificationSettings.alert, - "badge": UAAuthorizedNotificationSettings.badge, - "sound": UAAuthorizedNotificationSettings.sound, - "announcement": UAAuthorizedNotificationSettings.announcement, - "car_play": UAAuthorizedNotificationSettings.carPlay, - "critical_alert": UAAuthorizedNotificationSettings.criticalAlert, - "notification_center": UAAuthorizedNotificationSettings.notificationCenter, - "scheduled_delivery": UAAuthorizedNotificationSettings.scheduledDelivery, - "time_sensitive": UAAuthorizedNotificationSettings.timeSensitive, - "lock_screen": UAAuthorizedNotificationSettings.lockScreen +extension AirshipAuthorizedNotificationSettings { + private static let nameMap: [String: AirshipAuthorizedNotificationSettings] = [ + "alert": .alert, + "badge": .badge, + "sound": .sound, + "announcement": .announcement, + "car_play": .carPlay, + "critical_alert": .criticalAlert, + "notification_center": .notificationCenter, + "scheduled_delivery": .scheduledDelivery, + "time_sensitive": .timeSensitive, + "lock_screen": .lockScreen ] var names: [String] { var names: [String] = [] - UAAuthorizedNotificationSettings.nameMap.forEach { key, value in + AirshipAuthorizedNotificationSettings.nameMap.forEach { key, value in if (self.contains(value)) { names.append(key) } @@ -117,9 +117,9 @@ extension AirshipFeature { } } -extension UANotificationOptions { +extension UNAuthorizationOptions { - static let nameMap: [String: UANotificationOptions] = [ + static let nameMap: [String: UNAuthorizationOptions] = [ "alert": .alert, "badge": .badge, "sound": .sound, @@ -129,15 +129,15 @@ extension UANotificationOptions { "provisional": .provisional ] - static func parse(_ names: [Any]) throws -> UANotificationOptions { + static func parse(_ names: [Any]) throws -> UNAuthorizationOptions { guard let names = names as? [String] else { throw AirshipErrors.error("Invalid options \(names)") } - var options: UANotificationOptions = [] + var options: UNAuthorizationOptions = [] try names.forEach { name in - guard let option = UANotificationOptions.nameMap[name.lowercased()] else { + guard let option = UNAuthorizationOptions.nameMap[name.lowercased()] else { throw AirshipErrors.error("Invalid option \(name)") } options.update(with: option) @@ -148,7 +148,7 @@ extension UANotificationOptions { var names: [String] { var names: [String] = [] - UANotificationOptions.nameMap.forEach { key, value in + UNAuthorizationOptions.nameMap.forEach { key, value in if (self.contains(value)) { names.append(key) } diff --git a/ios/AirshipFrameworkProxy/AirshipProxyEvent.swift b/ios/AirshipFrameworkProxy/AirshipProxyEvent.swift index fed06b6..0851918 100644 --- a/ios/AirshipFrameworkProxy/AirshipProxyEvent.swift +++ b/ios/AirshipFrameworkProxy/AirshipProxyEvent.swift @@ -165,7 +165,7 @@ struct AuthorizedNotificationSettingsChangedEvent: AirshipProxyEvent { let body: [String: Any] init( - authorizedSettings: UAAuthorizedNotificationSettings + authorizedSettings: AirshipAuthorizedNotificationSettings ) { self.body = [ "authorizedSettings": authorizedSettings.names diff --git a/ios/AirshipFrameworkProxy/DefaultMessageCenterUI.swift b/ios/AirshipFrameworkProxy/DefaultMessageCenterUI.swift index e1ef6e6..1acf0ab 100644 --- a/ios/AirshipFrameworkProxy/DefaultMessageCenterUI.swift +++ b/ios/AirshipFrameworkProxy/DefaultMessageCenterUI.swift @@ -35,7 +35,7 @@ public class DefaultMessageCenterUI { self.currentDisplay = open( scene: scene, - theme: MessageCenter.shared.theme + theme: Airship.messageCenter.theme ) } @@ -52,7 +52,7 @@ public class DefaultMessageCenterUI { self.currentDisplay = openMessageView( scene: scene, messageID: messageID, - theme: MessageCenter.shared.theme + theme: Airship.messageCenter.theme ) } @@ -70,7 +70,7 @@ public class DefaultMessageCenterUI { let viewController = MessageCenterViewControllerFactory.make( theme: theme, - predicate: MessageCenter.shared.predicate, + predicate: Airship.messageCenter.predicate, controller: self.controller ) { cancellable.cancel() diff --git a/ios/AirshipFrameworkProxy/NotificationStatus.swift b/ios/AirshipFrameworkProxy/NotificationStatus.swift index 6441720..a1cc554 100644 --- a/ios/AirshipFrameworkProxy/NotificationStatus.swift +++ b/ios/AirshipFrameworkProxy/NotificationStatus.swift @@ -16,7 +16,7 @@ public struct NotificationStatus: Sendable, Equatable, Codable { self.isPushTokenRegistered = airshipStatus.isPushTokenRegistered self.isUserOptedIn = airshipStatus.isUserOptedIn self.isOptedIn = airshipStatus.isOptedIn - self.notificationPermissionStatus = airshipStatus.displayNotificationStatus.stringValue + self.notificationPermissionStatus = airshipStatus.displayNotificationStatus.rawValue } public let isUserNotificationsEnabled: Bool diff --git a/ios/AirshipFrameworkProxy/Proxies/AirshipAnalyticsProxy.swift b/ios/AirshipFrameworkProxy/Proxies/AirshipAnalyticsProxy.swift index 9045b1f..223a62b 100644 --- a/ios/AirshipFrameworkProxy/Proxies/AirshipAnalyticsProxy.swift +++ b/ios/AirshipFrameworkProxy/Proxies/AirshipAnalyticsProxy.swift @@ -28,17 +28,16 @@ public class AirshipAnalyticsProxy { } // Value - let customEvent: CustomEvent! - if let value = event["eventValue"] as? NSNumber { - customEvent = CustomEvent(name: name, value: value) - } else if let value = event["eventValue"] as? String { - customEvent = CustomEvent(name: name, stringValue: value) + var customEvent: CustomEvent = if let value = event["eventValue"] as? Double { + CustomEvent(name: name, value: value) + } else if let value = event["eventValue"] as? String, let double = Double(value) { + CustomEvent(name: name, value: double) } else { - customEvent = CustomEvent(name: name) + CustomEvent(name: name) } if let properties = event["properties"] as? [String: Any] { - customEvent.properties = properties + try customEvent.setProperties(properties) } if let transactionID = event["transactionId"] as? String { diff --git a/ios/AirshipFrameworkProxy/Proxies/AirshipContactProxy.swift b/ios/AirshipFrameworkProxy/Proxies/AirshipContactProxy.swift index c33d333..900afc6 100644 --- a/ios/AirshipFrameworkProxy/Proxies/AirshipContactProxy.swift +++ b/ios/AirshipFrameworkProxy/Proxies/AirshipContactProxy.swift @@ -50,7 +50,7 @@ public class AirshipContactProxy { lists.forEach { (key, value) in converted[key] = value.map { scope in - scope.stringValue + scope.rawValue } } diff --git a/ios/AirshipFrameworkProxy/Proxies/AirshipMessageCenterProxy.swift b/ios/AirshipFrameworkProxy/Proxies/AirshipMessageCenterProxy.swift index e90b8e9..e73aafc 100644 --- a/ios/AirshipFrameworkProxy/Proxies/AirshipMessageCenterProxy.swift +++ b/ios/AirshipFrameworkProxy/Proxies/AirshipMessageCenterProxy.swift @@ -93,8 +93,11 @@ public class AirshipMessageCenterProxy { } protocol MessageCenterProtocol: AnyObject { + @MainActor func display() + @MainActor func display(messageID: String) + @MainActor func dismiss() func message(forID messageID: String) async throws -> AirshipMessageCenterMessage var messages: [AirshipMessageCenterMessage] { get async } diff --git a/ios/AirshipFrameworkProxy/Proxies/AirshipPreferenceCenterProxy.swift b/ios/AirshipFrameworkProxy/Proxies/AirshipPreferenceCenterProxy.swift index fb13c6a..43eb903 100644 --- a/ios/AirshipFrameworkProxy/Proxies/AirshipPreferenceCenterProxy.swift +++ b/ios/AirshipFrameworkProxy/Proxies/AirshipPreferenceCenterProxy.swift @@ -13,19 +13,20 @@ public class AirshipPreferenceCenterProxy { private let proxyStore: ProxyStore - private let preferenceCenterProvider: () throws -> AirshipPreferenceCenterProtocol - private var preferenceCenter: AirshipPreferenceCenterProtocol { + private let preferenceCenterProvider: () throws -> PreferenceCenter + private var preferenceCenter: PreferenceCenter { get throws { try preferenceCenterProvider() } } init( proxyStore: ProxyStore, - preferenceCenterProvider: @escaping () throws -> AirshipPreferenceCenterProtocol + preferenceCenterProvider: @escaping () throws -> PreferenceCenter ) { self.proxyStore = proxyStore self.preferenceCenterProvider = preferenceCenterProvider } - + + @MainActor public func displayPreferenceCenter(preferenceCenterID: String) throws { try self.preferenceCenter.open(preferenceCenterID) } @@ -56,10 +57,3 @@ public class AirshipPreferenceCenterProxy { return converted } } - -protocol AirshipPreferenceCenterProtocol: AnyObject { - func open(_ preferenceCenterID: String) - func jsonConfig(preferenceCenterID: String) async throws -> Data -} - -extension PreferenceCenter: AirshipPreferenceCenterProtocol {} diff --git a/ios/AirshipFrameworkProxy/Proxies/AirshipProxy.swift b/ios/AirshipFrameworkProxy/Proxies/AirshipProxy.swift index f0be8e0..f4d91af 100644 --- a/ios/AirshipFrameworkProxy/Proxies/AirshipProxy.swift +++ b/ios/AirshipFrameworkProxy/Proxies/AirshipProxy.swift @@ -35,7 +35,7 @@ public class AirshipProxy { private var subscriptions: Set = Set() private let proxyStore: ProxyStore - private let airshipDelegate: AirshipDelegate + private var airshipDelegate: AirshipDelegate? public let locale: AirshipLocaleProxy public let push: AirshipPushProxy @@ -74,18 +74,18 @@ public class AirshipProxy { proxyStore: proxyStore ) { try AirshipProxy.ensureAirshipReady() - return MessageCenter.shared + return Airship.messageCenter } self.preferenceCenter = AirshipPreferenceCenterProxy( proxyStore: proxyStore ) { try AirshipProxy.ensureAirshipReady() - return PreferenceCenter.shared + return Airship.preferenceCenter } self.inApp = AirshipInAppProxy { try AirshipProxy.ensureAirshipReady() - return InAppAutomation.shared + return Airship.inAppAutomation } self.contact = AirshipContactProxy { @@ -110,10 +110,9 @@ public class AirshipProxy { self.featureFlagManager = AirshipFeatureFlagManagerProxy { try AirshipProxy.ensureAirshipReady() - return FeatureFlagManager.shared + return Airship.featureFlagManager } - self.airshipDelegate = AirshipDelegate(proxyStore: proxyStore) } @@ -168,15 +167,17 @@ public class AirshipProxy { AirshipLogger.debug("attemptTakeOff: \(String(describing: launchOptions))") - let airshipConfig = try makeConfig() + let airshipConfig = makeConfig() + + self.airshipDelegate = AirshipDelegate(proxyStore: proxyStore) AirshipLogger.debug("Taking off! \(airshipConfig)") - Airship.takeOff(airshipConfig, launchOptions: launchOptions) + try Airship.takeOff(airshipConfig, launchOptions: launchOptions) Airship.deepLinkDelegate = self.airshipDelegate Airship.push.registrationDelegate = self.airshipDelegate Airship.push.pushNotificationDelegate = self.airshipDelegate - PreferenceCenter.shared.openDelegate = self.airshipDelegate - MessageCenter.shared.displayDelegate = self.airshipDelegate + Airship.preferenceCenter.openDelegate = self.airshipDelegate + Airship.messageCenter.displayDelegate = self.airshipDelegate Airship.push.notificationStatusPublisher .map { status in @@ -200,12 +201,15 @@ public class AirshipProxy { await EmbeddedEventEmitter.shared.start() } + let delegate = self.airshipDelegate NotificationCenter.default.addObserver( forName: AirshipNotifications.MessageCenterListUpdated.name, object: nil, queue: .main ) { _ in - self.airshipDelegate.messageCenterInboxUpdated() + MainActor.assumeIsolated { + delegate?.messageCenterInboxUpdated() + } } NotificationCenter.default.addObserver( @@ -213,7 +217,9 @@ public class AirshipProxy { object: nil, queue: .main ) { _ in - self.airshipDelegate.channelCreated() + MainActor.assumeIsolated { + delegate?.channelCreated() + } } Airship.push.defaultPresentationOptions = self.proxyStore.foregroundPresentationOptions @@ -242,8 +248,8 @@ public class AirshipProxy { } @MainActor - private func makeConfig() throws -> AirshipConfig { - let airshipConfig: AirshipConfig = delegate?.loadDefaultConfig() ?? AirshipConfig.default() + private func makeConfig() -> AirshipConfig { + var airshipConfig: AirshipConfig = delegate?.loadDefaultConfig() ?? (try? AirshipConfig.default()) ?? AirshipConfig() airshipConfig.requireInitialRemoteConfigEnabled = true if let config = self.proxyStore.config { @@ -252,12 +258,6 @@ public class AirshipProxy { AirshipProxy.extender?.extendConfig(config: airshipConfig) - guard airshipConfig.validate() else { - throw AirshipProxyError.invalidConfig( - "Invalid config: \(String(describing: airshipConfig))" - ) - } - return airshipConfig } } diff --git a/ios/AirshipFrameworkProxy/Proxies/AirshipPushProxy.swift b/ios/AirshipFrameworkProxy/Proxies/AirshipPushProxy.swift index d62e9b4..10c2277 100644 --- a/ios/AirshipFrameworkProxy/Proxies/AirshipPushProxy.swift +++ b/ios/AirshipFrameworkProxy/Proxies/AirshipPushProxy.swift @@ -45,14 +45,16 @@ public class AirshipPushProxy { ) } + @MainActor public func getRegistrationToken() throws -> String? { return try self.push.deviceToken } + @MainActor public func setNotificationOptions( names:[String] ) throws { - let options = try UANotificationOptions.parse(names) + let options = try UNAuthorizationOptions.parse(names) try self.push.notificationOptions = options } diff --git a/ios/AirshipFrameworkProxy/ProxyConfig.swift b/ios/AirshipFrameworkProxy/ProxyConfig.swift index c5e7457..92ad20b 100644 --- a/ios/AirshipFrameworkProxy/ProxyConfig.swift +++ b/ios/AirshipFrameworkProxy/ProxyConfig.swift @@ -175,7 +175,7 @@ extension ProxyConfig.Site { extension AirshipConfig { - public func applyProxyConfig(proxyConfig: ProxyConfig) { + public mutating func applyProxyConfig(proxyConfig: ProxyConfig) { // App credentials if let appKey = proxyConfig.defaultEnvironment?.appKey, let appSecret = proxyConfig.defaultEnvironment?.appSecret { diff --git a/ios/AirshipFrameworkProxy/ScopedSubscriptionListOperation.swift b/ios/AirshipFrameworkProxy/ScopedSubscriptionListOperation.swift index d8aa41a..2d5eade 100644 --- a/ios/AirshipFrameworkProxy/ScopedSubscriptionListOperation.swift +++ b/ios/AirshipFrameworkProxy/ScopedSubscriptionListOperation.swift @@ -35,7 +35,7 @@ public struct ScopedSubscriptionListOperation: Decodable, Equatable { let container = try decoder.container(keyedBy: CodingKeys.self) self.action = try container.decode(ScopedSubscriptionListOperation.Action.self, forKey: .action) self.listID = try container.decode(String.self, forKey: .listID) - self.scope = try ChannelScope.fromString(container.decode(String.self, forKey: .scope)) + self.scope = try container.decode(ChannelScope.self, forKey: .scope) } func apply(editor: ScopedSubscriptionListEditor) { diff --git a/ios/Podfile b/ios/Podfile index e086765..f205532 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ target 'AirshipFrameworkProxy' do - pod 'Airship', '18.14.2' + pod 'Airship', '19.0.0' end target 'AirshipFrameworkProxyTests' do diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 89b807c..356225b 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,33 +1,33 @@ PODS: - - Airship (18.14.2): - - Airship/Automation (= 18.14.2) - - Airship/Basement (= 18.14.2) - - Airship/Core (= 18.14.2) - - Airship/FeatureFlags (= 18.14.2) - - Airship/MessageCenter (= 18.14.2) - - Airship/PreferenceCenter (= 18.14.2) - - Airship/Automation (18.14.2): + - Airship (19.0.0): + - Airship/Automation (= 19.0.0) + - Airship/Basement (= 19.0.0) + - Airship/Core (= 19.0.0) + - Airship/FeatureFlags (= 19.0.0) + - Airship/MessageCenter (= 19.0.0) + - Airship/PreferenceCenter (= 19.0.0) + - Airship/Automation (19.0.0): - Airship/Core - - Airship/Basement (18.14.2) - - Airship/Core (18.14.2): + - Airship/Basement (19.0.0) + - Airship/Core (19.0.0): - Airship/Basement - - Airship/FeatureFlags (18.14.2): + - Airship/FeatureFlags (19.0.0): - Airship/Core - - Airship/MessageCenter (18.14.2): + - Airship/MessageCenter (19.0.0): - Airship/Core - - Airship/PreferenceCenter (18.14.2): + - Airship/PreferenceCenter (19.0.0): - Airship/Core DEPENDENCIES: - - Airship (= 18.14.2) + - Airship (= 19.0.0) SPEC REPOS: trunk: - Airship SPEC CHECKSUMS: - Airship: f293470bde4a4cbd23ac73dbda986629d9ad9fdb + Airship: 0b26712fb551e96c3f9e790352059ff8fd3eb920 -PODFILE CHECKSUM: dfb77155ca86afc9a9a614575d148225c348afe6 +PODFILE CHECKSUM: ab38d40ed32564525fb61f381e4782f404878bf9 -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2