diff --git a/iosClient/iosClient/iosClient.swift b/iosClient/iosClient/iosClient.swift index f105b707..3b157f41 100644 --- a/iosClient/iosClient/iosClient.swift +++ b/iosClient/iosClient/iosClient.swift @@ -1,10 +1,22 @@ import SwiftUI +import domain import presentation @main struct iosClient: App { + +// private let notificationServiceController: NotificationServiceController? + private let notificationHandler = NotificationHandler() + init() { DependenciesProviderHelper().doInitKoin() +// TODO not working +// notificationServiceController = get() +// if (notificationServiceController != nil) { +// notificationHandler.setNotificationHandlerImpl(notificationServiceController!) +// } +// // Request notification permissions and set the delegate +// configureNotifications() } var body: some Scene { @@ -12,4 +24,59 @@ struct iosClient: App { ContentView() } } + + private func configureNotifications() { + let center = UNUserNotificationCenter.current() + center.delegate = notificationHandler // Custom delegate + + center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in + if let error = error { + print("Error requesting notifications permission: \(error)") + } + if granted { + DispatchQueue.main.async { + UIApplication.shared.registerForRemoteNotifications() + } + } + } + UNUserNotificationCenter.current().getNotificationSettings { settings in + print("Notification settings: \(settings)") + if settings.authorizationStatus == .authorized { + print("Notifications are authorized.") + } else { + print("Notifications are not authorized.") + } + } + + // simulation + let content = UNMutableNotificationContent() + content.title = "Test Notification" + content.body = "This is a test notification." + content.sound = .default + + let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil) + UNUserNotificationCenter.current().add(request) { error in + if let error = error { + print("Failed to add notification: \(error)") + } else { + print("Notification added successfully") + } + } + } } + +// Custom notification handler that conforms to `UNUserNotificationCenterDelegate` +class NotificationHandler: NSObject, UNUserNotificationCenterDelegate { + private var impl: NotificationServiceController? + + func setNotificationHandlerImpl(_ controller: NotificationServiceController) { + self.impl = controller + } + + func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { + // Show the notification while in foreground + print("Foreground notification received") + completionHandler([.banner, .sound, .badge]) + impl?.pushNotification(title: "pepe", message: "parada") + } +} \ No newline at end of file diff --git a/shared/domain/src/iosMain/kotlin/network/bisq/mobile/domain/service/controller/NotificationServiceController.ios.kt b/shared/domain/src/iosMain/kotlin/network/bisq/mobile/domain/service/controller/NotificationServiceController.ios.kt index a0b2ced5..6e144d12 100644 --- a/shared/domain/src/iosMain/kotlin/network/bisq/mobile/domain/service/controller/NotificationServiceController.ios.kt +++ b/shared/domain/src/iosMain/kotlin/network/bisq/mobile/domain/service/controller/NotificationServiceController.ios.kt @@ -14,6 +14,10 @@ @Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING") actual class NotificationServiceController: ServiceController, Logging { + companion object { + const val BACKGROUND_TASK_ID = "network.bisq.mobile.ios.backgroundtask" + } + private var isRunning = false private val logScope = CoroutineScope(Dispatchers.Main) @@ -41,7 +45,7 @@ logDebug("Notification permission granted.") // TODO need to move to iOS callback -> didFinishLaunchingWithOptions - BGTaskScheduler.sharedScheduler.registerForTaskWithIdentifier(identifier = "network.bisq.mobile.ios.backgroundtask", usingQueue = null) { task -> + BGTaskScheduler.sharedScheduler.registerForTaskWithIdentifier(identifier = BACKGROUND_TASK_ID, usingQueue = null) { task -> handleBackgroundTask(task as BGProcessingTask) } scheduleBackgroundTask() @@ -92,7 +96,7 @@ @OptIn(ExperimentalForeignApi::class) private fun scheduleBackgroundTask() { - val request = BGProcessingTaskRequest("com.yourapp.backgroundtask").apply { + val request = BGProcessingTaskRequest(BACKGROUND_TASK_ID).apply { requiresNetworkConnectivity = true } BGTaskScheduler.sharedScheduler.submitTaskRequest(request, null) diff --git a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/MainPresenter.kt b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/MainPresenter.kt index 44605aa2..193a585c 100644 --- a/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/MainPresenter.kt +++ b/shared/presentation/src/commonMain/kotlin/network/bisq/mobile/presentation/MainPresenter.kt @@ -6,8 +6,10 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.launch import network.bisq.mobile.android.node.BuildNodeConfig import network.bisq.mobile.client.shared.BuildConfig +import network.bisq.mobile.domain.data.BackgroundDispatcher import network.bisq.mobile.domain.getPlatformInfo import network.bisq.mobile.domain.service.controller.NotificationServiceController import network.bisq.mobile.presentation.ui.AppPresenter