目前,我在AppDelegate中实现了这两种方法
func application(application: UIApplication,continueUserActivity userActivity: NSUserActivity,restorationHandler: ([AnyObject]?) -> Void) -> Bool
和
func application(app: UIApplication,openURL url: NSURL,options: [String : AnyObject]) -> Bool
如果用户使用Spotlight的搜索结果打开我的应用程序,第一个将被调用,如果我的应用程序从Apple Maps打开,则第二个将被调用(因为它是路由应用程序).
我的问题是,什么是从APPDELEGATE转到特定UIViewController的最佳方式(独立于用户所处的视图)?
我问的原因是因为目前我正在尝试根据用户的位置手动导航到它.例如,它们可能位于以模态方式显示的UIViewController中(然后需要被解除),或者它们可能位于UINavigationController深处,然后应用程序需要调用popToRootViewController.
这样做,代码变得毛茸茸,似乎无法正常工作.以这种方式做这件事似乎也不对,因为它非常脆弱.
解决方法
我只是想弄清楚如何实现你提到的第一种方法,并从
https://www.hackingwithswift.com/read/32/4/how-to-add-core-spotlight-to-index-your-app-content开始找到一个有用的开端
他的代码是:
他的代码是:
func application(application: UIApplication,restorationHandler: ([AnyObject]?) -> Void) -> Bool { if userActivity.activityType == CSSearchableItemActionType { if let uniqueIdentifier = userActivity.userInfo?[CSSearchableItemActivityIdentifier] as? String { let splitViewController = self.window!.rootViewController as! UISplitViewController let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as! UINavigationController if let masterVC = navigationController.topViewController as? MasterViewController { masterVC.showTutorial(Int(uniqueIdentifier)!) } } } return true }
我发现self.window?.rootViewController为? yourRootViewControllerClass是你问题的好跳板.
我的代码非常基本,看起来像这样:
// create a storyBoard item to instantiate a viewController from. If you have multiple storyboards,use the appropriate one. I just have one so it is "Main" let sb = UIStoryboard(name: "Main",bundle: nil) // get the navigation controller from the window and instantiate the viewcontroller I need. if let viewController = sb.instantiateViewControllerWithIdentifier("DetailViewController") as? ViewController,let nav = window?.rootViewController as? UINavigationController { viewController.setupController(bookName)// setup the viewController however you need to. I have a method that I use (I grabbed the bookName variable from the userActivity) nav.pushViewController(viewController,animated: false)//use the navigation controller to present this view. }
这对我有用,但我必须提出一个警告.我的应用只有一个故事板,有三个viewControllers(NavController-> tableViewController-> ViewController).我不确定这种逻辑如何适用于更复杂的应用程序.
另一个很好的参考是:http://www.appcoda.com/core-spotlight-framework/
func application(application: UIApplication,restorationHandler: ([AnyObject]?) -> Void) -> Bool { let viewController = (window?.rootViewController as! UINavigationController).viewControllers[0] as! ViewController viewController.restoreUserActivityState(userActivity) return true }
那个viewController有这个方法:
override func restoreUserActivityState(activity: NSUserActivity) { if activity.activityType == CSSearchableItemActionType { if let userInfo = activity.userInfo { let selectedMovie = userInfo[CSSearchableItemActivityIdentifier] as! String selectedMovieIndex = Int(selectedMovie.componentsSeparatedByString(".").last!) performSegueWithIdentifier("idSegueShowMovieDetails",sender: self) } } }