2

目前具体视图控制器,我已经在我的AppDelegate实现这两种方法导航从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

这样做,代码变得毛茸茸的,似乎并不正确。这样做似乎也不正确,要么是因为它非常脆弱。

+0

检查这个http://stackoverflow.com/a/26757245/3535399 –

+0

@vivektakrani,不完全我在找什么...这些都是viewDidFinishLaunchingWithOptions ...只发生一次。我在谈论另外两种委托方法(在我的文章中提到),如果用户来自Apple Maps或Spotlight,那么这两种方法都会发生 - 在应用程序的整个生命周期中,这两种方法都可以很快乐。 –

回答

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) 
     } 
    } 
}