Open controller from app delegate - ios

I am trying to open a view controller from app delegate if a push notification is clicked with the code below
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
if(application.applicationState==UIApplicationState.Inactive ){
let sdViewController = mainStoryboardIpad.instantiateViewControllerWithIdentifier("StudentViewController") as! StudentViewController
let navController = UINavigationController(rootViewController: sdViewController)
navController.setViewControllers([sdViewController], animated:true)
self.window?.rootViewController = navController
}
}
The controller opens, however the menu icon to reveal the navigation does not work. How can i make the menu icon reveal the side navigation.

Try this
let rootViewController = self.window!.rootViewController as! UINavigationController
rootViewController.pushViewController(sdViewController, animated: true)

Related

How to navigate the user to required view controller on tap of deep link for fresh installation of app with firebase

I want to navigate the user to specific view controller on click of deep linking
If a user already installed the app I am able do by using below method in app delegate
application(_ application: UIApplication, continue userActivity: NSUserActivity,
restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool
But how to navigate the user to desired ViewController for first time installation of app
Maybe you can use UserDefaults...
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
let alreadyInitialized = UserDefaults.standard.bool(forKey: "AlreadyInitialized")
if !alreadyInitialized {
UserDefaults.set(true, forKey: "AlreadyInitialized")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let destinationViewController = storyboard.instantiateViewControllerWithIdentifier("FirstTimeViewController") as FirstTimeViewController
let navigationController = self.window?.rootViewController as! UINavigationController
navigationController?.pushViewController(destinationViewController, animated: false, completion: nil)
}
}

3D Touch Quick Action Won't work swift 3

I am trying to add 3D touch quick action in my app. I have two viewContollers embedded in navigationContoller. When the user press on the 3D action, it should take them to the add events viewController. But i am getting this error
could not cast value of type 'Morning_Star_2.AddEventsViewController' (0x1000a2260) to 'UINavigationController' (0x1a79cd360).
2017-05-02 02:51:36.220324-0400 Morning Star 2[3731:895126] Could not cast value of type 'Morning_Star_2.AddEventsViewController' (0x1000a2260) to 'UINavigationController' (0x1a79cd360).
Here is my code
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: #escaping (Bool) -> Void) {
if shortcutItem.type == "com.krp.addEvent" {
let sb = UIStoryboard(name: "Main", bundle: nil)
let addEventVC = sb.instantiateViewController(withIdentifier: "addEventVC") as! UINavigationController
self.window?.rootViewController?.present(addEventVC, animated: true, completion: nil)
}
}
I tried changing as! UINavigationController to as! AddEventsViewController. It works, but then it won't show the navigation bar on the top on my add viewController as it normally would if you open the app normally.
Here is my main.storyboard
You shouldn't cast AddEventsViewController to UINavigationController, because it isn't UINavigationController, is just subclass of UIViewController. But as I see, your rootViewController is. So you need to cast it to UINavigationController, and then push your AddEventsViewController, instead present, and you will see NavigationBar
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: #escaping (Bool) -> Void) {
if shortcutItem.type == "com.krp.addEvent" {
let sb = UIStoryboard(name: "Main", bundle: nil)
let addEventVC = sb.instantiateViewController(withIdentifier: "addEventVC") as! AddEventsViewController
if let navigationController = window?.rootViewController as? UINavigationController {
navigationController.pushViewController(addEventVC, animated: true)
}
}
}

Swift - How to open specific view controller when push notification received?

I got stuck specific view controller is not move when I tap on push notification alert when application is not open stage totally.
Here is my code:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
/*
fetch and add push notification data
*/
goAnotherVC()
}
func goAnotherVC() {
if (application.applicationState == UIApplicationState.active) {
/* active stage is working */
} else if (application.applicationState == UIApplicationState.inactive || application.applicationState == UIApplicationState.background) {
if (type == "1" || type == "2") {
let storyboard: UIStoryboard = UIStoryboard(name: "MyAppointments", bundle: nil)
let apptVC = storyboard.instantiateViewController(withIdentifier: "NotificationDetailViewController") as! NotificationDetailViewController
let navigationController = UINavigationController.init(rootViewController: apptVC)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
} else if (type == "3") {
let storyboard: UIStoryboard = UIStoryboard(name: "MyAppointments", bundle: nil)
let apptVC = storyboard.instantiateViewController(withIdentifier: "NotificationDetailViewController") as! NotificationDetailViewController
let navigationController = UINavigationController.init(rootViewController: apptVC)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
} else if (type == "4") {
let storyboard: UIStoryboard = UIStoryboard(name: "Enquiry", bundle: nil)
let enqVC = storyboard.instantiateViewController(withIdentifier: "EnquiryDetailViewController") as! EnquiryDetailViewController
let navigationController = UINavigationController.init(rootViewController: enqVC)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
}
}
}
I can get notification and tap to move specific VC when application is active. Please help me what I am missing.
Swift 5
Simply, implement the following function which will be called when the user clicked on the notification.
In AppDelegate:
// This method is called when user clicked on the notification
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void)
{
// Do whatever you want when the user tapped on a notification
// If you are waiting for specific data from the notification
// (e.g., key: "target" and associated with "value"),
// you can capture it as follows then do the navigation:
// You may print `userInfo` dictionary, to see all data received with the notification.
let userInfo = response.notification.request.content.userInfo
if let targetValue = userInfo["target"] as? String, targetValue == "value"
{
coordinateToSomeVC()
}
completionHandler()
}
private func coordinateToSomeVC()
{
guard let window = UIApplication.shared.keyWindow else { return }
let storyboard = UIStoryboard(name: "YourStoryboard", bundle: nil)
let yourVC = storyboard.instantiateViewController(identifier: "yourVCIdentifier")
let navController = UINavigationController(rootViewController: yourVC)
navController.modalPresentationStyle = .fullScreen
// you can assign your vc directly or push it in navigation stack as follows:
window.rootViewController = navController
window.makeKeyAndVisible()
}
Note:
If you navigate to a specific controller based on the notification, you should care about how you will navigate back from this controller because there are no controllers in your stack right now. You must instantiate the controller you will back to. In my case, when the user clicked back, I instantiate the home controller and make it the app root again as the app will normally start.
When you app is in closed state you should check for launch option in
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { }
and call your API.
Example:
if let option = launchOptions {
let info = option[UIApplicationLaunchOptionsKey.remoteNotification]
if (info != nil) {
goAnotherVC()
}
}
Swift 5, iOS 13 -
Since iOS 13 "window" is available in SceneDelegate. But the didReceiveNotification method is still present in AppDelegate.
So you have to first access the window from SceneDelegate
let window = (UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.window
Now You can set the rootViewController property of the window
window.rootViewController = viewControllerObject
window.makeKeyAndVisible()

3d touch swift 3 does not open the viewcontroller

I got a 3d touch function in my app delegate for the shortcutitems and it has to instantiate a viewcontroller when 3d touch item clicked from the iphone.
Here is the code:
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: #escaping (Bool) -> Void) {
if shortcutItem.type == "com.kevinvugts.addStuf" {
let sb = UIStoryboard(name: "Main", bundle: nil)
let exerciseVC = sb.instantiateViewController(withIdentifier: "exerciseVC") as! exerciseVC
let root = UIApplication.shared.keyWindow?.rootViewController
root?.present(exerciseVC, animated: false, completion: { () -> Void in
completionHandler(true)
})
}
}
This code results in this warning/error:
Warning: Attempt to present <ActiveRest.exerciseVC: 0x131d39320> on <ActiveRest.ViewController: 0x131d0e470> whose view is not in the window hierarchy!
Has this anything to do with delay?
Thanks for any help!
Kind Regards.
view is not in the window hierarchy that means your view of your viewcontroller is not loaded in memory still. so you are unable to present viewcontroller on it. you should have to present viewcontroller from viewDidAppear of your viewcontroller (I mean from your rootviewController).
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: #escaping (Bool) -> Void) {
if shortcutItem.type == "com.kevinvugts.addStuf" {
let sb = UIStoryboard(name: "Main", bundle: nil)
let exerciseVC = sb.instantiateViewController(withIdentifier: "exerciseVC") as! exerciseVC
window?.rootViewController?.addChildViewController(exerciseVC)
}
}
I made this change and everything works fine.

From AppDelegate didreceiveremotenotification navigate to a certain viewcontrolller - swift

I have my TabBarController as my initial view (storyboard identity Main) (Class UITabBarController)
Then a NavigationController (storyboard id = ViewController) (Class UINavigationController).
Then my ViewController (storyboard id = View) (Class ViewController)
Then my Details (storyboard id = StoryDetails) (Class Details)
I would like to navigate from AppDelegate.swift to the Details.swift uiviewcontroller.
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
if let tabViewController = storyboard.instantiateViewControllerWithIdentifier("StoryDetails") as? UITabBarController {
window!.rootViewController!.presentViewController(tabViewController, animated: true, completion: nil)
}
But this is not working
Help would be really appreciated! (:
Also
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let detail = storyboard.instantiateViewControllerWithIdentifier("StoryDetails")
self.window?.rootViewController!.presentViewController(detail, animated: true, completion: nil)
This code brings up the view, but there is no navigation controller or tab bar controller

Resources