我正在尝试在我的应用中设置深层链接。我已经设置了应用程序以及推送通知。但是,我无法从 AppDelegate 接收用户单击通知到我想要深层链接到的屏幕的位置完成最终链接。我基本上想从 AppDelegate 调用 viewRouter.goToFred()。我在此处 (https://github.com/cameronhenige/SwiftUITestDeepLink) 设置了一个 git 存储库,其中包含一个应用程序,该应用程序设置了除最后一部分之外的所有内容。有人可以帮我解决这个问题吗?这是相关的代码片段。谢谢!
import SwiftUI
struct MainView: View {
@EnvironmentObject var viewRouter: ViewRouter
var body: some View {
NavigationView {
List {
ForEach(viewRouter.pets) { pet in
NavigationLink(
destination: PetView(),
tag: pet,
selection: $viewRouter.selectedPet,
label: {
Text(pet.name)
}
)
}
Button("Send Notification to Fred") {
viewRouter.sendNotification()
}
Button("Manually go to Fred") {
viewRouter.goToFred()
}
}
}
}
}
struct MainView_Previews: PreviewProvider {
static var previews: some View {
MainView()
}
}
import SwiftUI
@main
struct ContentView: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
MainView().environmentObject(ViewRouter())
}
}
}
import Foundation
import UserNotifications
class ViewRouter: ObservableObject {
@Published var selectedPet: Pet? = nil
@Published var pets: [Pet] = [Pet(name: "Louie"), Pet(name: "Fred"), Pet(name: "Stanley")]
func goToFred() {
self.selectedPet = pets[1]
}
func sendNotification() {
let content = UNMutableNotificationContent()
let categoryIdentifire = "Notification Type"
content.title = "Go To Fred"
content.body = "Click me to go to Fred."
content.sound = UNNotificationSound.default
content.badge = 1
content.categoryIdentifier = categoryIdentifire
let request = UNNotificationRequest(identifier: "identifier", content: content, trigger: nil)
UNUserNotificationCenter.current().add(request) { (error) in
if let error = error {
print("Error \(error.localizedDescription)")
}
}
}
}
import SwiftUI
struct PetView: View {
@EnvironmentObject var viewRouter: ViewRouter
var body: some View {
if let pet = viewRouter.selectedPet {
Text(pet.name)
} else {
EmptyView()
}
}
}
struct PetView_Previews: PreviewProvider {
static var previews: some View {
PetView()
}
}
import Foundation
struct Pet: Identifiable, Hashable {
var name: String
var id: String { name }
}
import Foundation
import UIKit
class AppDelegate: UIResponder, UIApplicationDelegate {
let notificationCenter = UNUserNotificationCenter.current()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
return true
}
}
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
print("Notification created")
// Change this to your preferred presentation option
completionHandler([[.alert, .sound]])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
print("user clicked on notification. Now take them to Fred.")
//todo Somehow I want to call viewRouter.goToFred(), but I don't have access to that object in AppDelegate
completionHandler()
}
}
答案 0 :(得分:1)
我尝试了这种方法并且它有效。诚然,我不知道这是正确的还是建议的方法。
appDelegate
必须获得对 MainView 正在使用的同一个 ViewRouter
实例的引用,并且 ContentView
必须将 appDelegate
与 ViewRouter
挂钩实例。
ContentView.swift:
@main
struct ContentView: App {
let router = ViewRouter()
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
MainView()
.environmentObject(router)
.onAppear(perform:setUpAppDelegate)
}
}
func setUpAppDelegate(){
appDelegate.router = router
}
}
AppDelegate.swift:
weak var router: ViewRouter?
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
print("user clicked on notification. Now take them to Fred.")
//todo Update the ViewRouter to
router?.goToFred()
completionHandler()
}
答案 1 :(得分:0)
您只需在 AppDelegate 的 userNotificationCenter(_:didReceive:withCompletionHandler:)
中点击通知时调用您想要运行的方法