目前,我已在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打开,则第二个将被调用(因为它是路由应用程序)。
我的问题是,什么是最适合特定UIViewController
来自APPDELEGATE的方式(独立于用户所处的视图)?
我问的原因是因为目前我正在尝试根据用户的位置手动导航到它。例如,它们可能位于UIViewController
模式显示(然后需要被解除),或者它们可能位于UINavigationController
深处,然后应用程序需要调用{{1} }}。
这样做,代码变得毛茸茸,似乎无法正常工作。以这种方式做这件事似乎也不对,因为它非常脆弱。
答案 0 :(得分:0)
我只是想弄清楚如何实现您提到的第一种方法,并从https://www.hackingwithswift.com/read/32/4/how-to-add-core-spotlight-to-index-your-app-content找到一个有用的开端 他的代码是:
func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, 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, continueUserActivity userActivity: NSUserActivity, 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)
}
}
}
答案 1 :(得分:0)
我认为,重新导航的好地方是事件UIApplicationDidBecomeActiveNotification
,该事件在根视图控制器中已订阅(无论使用什么方式)。
当您在AppDelegate
中执行代码时,只需安排一个动作:用抽象数量的属性,数据参数等组合您的包裹。将其存储在某个地方(NSUserDefauils-是个不错的地方,但甚至可能是SqlCipher实例)。并保持休息,希望接下来的活动。
触发UIApplicationDidBecomeActiveNotification
时-醒来,捕获存储的Action parcell,并根据Action属性执行重新导航。
关于模态视图控制器。他们(确切地说,是世界卫生组织展示的控制者)应该准备好在重新导航事件到来时解散他们以模态显示的所有VC。