2 years ago
#63165
John Sorensen
Programmatic Navigation after opening notification SwiftUI
So I have a bunch of UIKit code to enable my iOS app to receive notifications. How do I programmatically navigate upon a user opening a notification?
Code to Receive Notifications:
class AppDelegate: NSObject, UIApplicationDelegate {
let gcmMessageIDKey = "gcm.message_id"
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
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
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceTokenL: Data) {
}
}
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?){
print("Firebase Registration Token: \(String(describing: fcmToken))")
let dataDict: [String: String] = ["token": fcmToken ?? ""]
print(dataDict)
// store here
}
}
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping
(UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
print(userInfo)
completionHandler([[.banner, .badge, .sound]])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
}
}
My app delegate is instantiated here:
@main
struct MRPApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
My ContentView
is what has the navigation functionality:
struct ContentView: View {
@State var selectedTab: MenuTab = .first
var body: some View {
NavigationView {
VStack {
if selectedTab == .first {
Text("First Screen")
.frame(maxHeight: .infinity)
} else if selectedTab == .second {
Text("Second Screen")
.frame(maxHeight: .infinity)
} else if selectedTab == .third {
Text("Third Screen")
.frame(maxHeight: .infinity)
}
TabPicker(selectedTab: $selectedTab)
}
}
}
}
enum MenuTab {
case first
case second
case third
}
struct TabPicker: View {
@Binding var selectedTab: MenuTab
var body: some View {
HStack {
Spacer()
Text("1")
.fontWeight( selectedTab == .first ? .bold: .light)
.onTapGesture { selectedTab = .first }
Spacer()
Text("2")
.fontWeight( selectedTab == .second ? .bold: .light)
.onTapGesture { selectedTab = .second }
Spacer()
Text("3")
.fontWeight( selectedTab == .third ? .bold: .light)
.onTapGesture { selectedTab = .third }
Spacer()
}
}
}
I assume that something in the UIKit code is triggered whenever a user opens a notification--how do pass that information to my ContentView? We can imagine that, depending on the type of notification, we might want the app to automatically navigate to any one of the three screens I have in this MRP.
P.S. (I just realized that technically I'm not using the NavigationView
)
swiftui
notifications
navigation
0 Answers
Your Answer