Я разрабатываю мобильное приложение веб-просмотра с использованием Swift на платформе iOS. В приложении я использую Universal Link и OneSignal. Когда приложение закрыто или находится в фоновом режиме и т. д. В любом случае deeplink работает отлично. Никаких проблем пока.
Проблема в натификации OneSignal. Если приложение закрыто и я отправляю push-уведомление с URL-адресом, я не могу перенаправить на соответствующий URL-адрес.
Нет проблем, если приложение открыто или работает в фоновом режиме. URL-адрес открывается в веб-просмотре. Однако, как я уже говорил, проблема возникает при закрытии приложения. Есть ли кто-нибудь, кто может мне помочь с этим?
Я думаю, что эта проблема должна быть решена в файле SceneDelegate.swift. Однако, хотя я перепробовал много вещей, я не смог найти решения. Кратко мои работы ниже:
// Файл AbcViewController.swift:
import UIKit
import WebKit
import OneSignalFramework
class AbcViewController: UIViewController {
@IBOutlet weak var webView: WKWebView!
var urlOneSignalNotification: URL?
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(handNotURL), name: Notification.Name(rawValue: "urlReceived"), object: nil)
// Define default URL
let defaultURL = URL(string: "example.com")!
let url = urlOneSignalNotification ?? defaultURL
var request = URLRequest(url: url)
webView.load(request)
}
// Get
@objc func handNotURL(_ notification: Notification) {
if let url = notification.object as? URL {
urlOneSignalNotification = url
// Load the URL in the web view
let request = URLRequest(url: urlOneSignalNotification!)
webView.load(request)
} else {
urlOneSignalNotification = nil
}
}
}
// AppDelegate.swift
import UIKit
import OneSignalFramework
import UserNotifications
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
//...
}
extension AppDelegate: UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
guard let data = userInfo as? [String: Any] else {
completionHandler(.noData)
return
}
if let customData = data["custom"] as? [String: Any], let urlString = customData["u"] as? String {
if let url = URL(string: urlString) {
NotificationCenter.default.post(name: Notification.Name(rawValue: "urlReceived"), object: url)
} else {
}
}
completionHandler(.newData)
}
}





После холодного запуска приложениям часто требуется некоторое время, чтобы быть готовыми к использованию, от main.swift до application:(_didFinishLauchingWithOptions:).
Таким образом, вы можете либо определить класс для хранения полезных данных из уведомлений и затем использовать его позже, когда приложение загрузится, либо создать wait прямо перед NotificationCenter.default.post.
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
NotificationCenter.default.post(name: Notification.Name(rawValue: "urlReceived"), object: url)
}
//Or
Task { @MainActor in
try? await Task.sleep(nanoseconds: 1_000_000_000)
NotificationCenter.default.post(name: Notification.Name(rawValue: "urlReceived"), object: url)
}