使用Facebook“iOS原生深度链接”和openURL与iOS 5故事板/ segue基于应用程序?

问题描述:

我已启用Facebook,iOS 5应用程序使用故事板和基于segue的导航,并且对如何实现“iOS原生深度链接”感到困惑。示例代码Improving App Distribution on iOS只显示UIAlertView,但我试图启动两个连续的seque操作。使用Facebook“iOS原生深度链接”和openURL与iOS 5故事板/ segue基于应用程序?

对于这个问题的目的,我已经简化了应用三个视图控制器:MYCategoryTableViewControllerMYItemsTableViewControllerMYItemViewController。在正常流程中,应用程序打开到MYCategoryTableViewController,显示一个类别表。当用户选择一个类别时,会跳转到MYItemsTableViewController,其中显示该选定类别的项目表。最后,当一个项目被选中时,会出现一个MYItemViewController,显示一个项目详细视图。

MYCategoryTableViewControllerprepareForSegue设置表示该类别中的目的地视图控制器上的属性:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    if ([[segue identifier] isEqualToString:@"ITEMS_SEGUE"]) { 
     MYItemsTableViewController *vc = [segue destinationViewController];   
     MYCategory *mycategory = [self.fetchedResultsController objectAtIndexPath:[self.tableView indexPathForSelectedRow]]; 
     vc.mycategory = mycategory; 
    } 
} 

prepareForSegueMYItemsTableViewController设置表示该类别中的目的地视图控制器上的属性:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    if ([[segue identifier] isEqualToString:@"ITEM_SEGUE"]) { 
     MYItemViewController *vc = [segue destinationViewController]; 
     MYItem *myitem = [self.fetchedResultsController objectAtIndexPath:[self.tableView indexPathForSelectedRow]]; 
     vc.myitem = myitem; 
    } 
} 

问题:我知道我需要在application:openURL中实现某些东西,但不知道是什么做下一步。假设传入的URL提供标识符来查找MYCategoryMYItem对象。我发现performSegueWithIdentifier,但不知道如何与prepareForSegue交互以及如何在目标视图控制器上设置我的模型对象。

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { 
    // get "target_url" from incoming url 
    // and parse out MYCategory and MYItem identifiers 

    // something like this??? 
    [self.window makeKeyAndVisible]; 
    [self.window.rootViewController performSegueWithIdentifier:@"ITEM_SEGUE" sender:self]; 

    return [facebook handleOpenURL:url]; 
} 

更新:Selecting programmatically a cell on a tableview doesn't perform associated segue给了我的想法。也许我只保存application:openURL:的网址,并自然加载MYCategoryTableViewController。然后在viewWillAppear期间,致电tableView selectRowAtIndexPath,然后performSegueWithIdentifier转换为MYItemsTableViewController。在MYItemsTableViewController重复相同的模式,但清除performSegueWithIdentifier呼叫之前的网址。

这是我得到的工作。在MYAppDelegate中,我捕获了一个代表深度链接标识的字符串。

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { 
    NSString *deepLinkId; 
    // more code that parses url 

    // only deep link if MYCategoryTableViewController is active controller 
    UIViewController *rootContoller = self.window.rootViewController; 
    if ([rootContoller isKindOfClass:[UINavigationController class]]) { 
     UINavigationController *navController = (UINavigationController *)rootContoller; 
     if ([navController.topViewController isKindOfClass:[MYCategoryTableViewController class]]) { 
      self.deepLinkId = deepLinkId; 
     } 
    } 
} 

然后,当MYCategoryTableViewController负荷,调用selectRowAtIndexPath然后performSegueWithIdentifier

- (void)processDeepLink { 
    if (_appDelegate.deepLinkId) { 
     MYItem *myitem = [MYItem lookupById:_appDelegate.deepLinkId inManagedObjectContext:_appDelegate.dataDocument.managedObjectContext]; 
     if (myitem) { 
      NSIndexPath *indexPath = [self.fetchedResultsController indexPathForObject:myitem.mycategory]; 
      [self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionMiddle]; 
      [self performSegueWithIdentifier:@"ITEMS_SEGUE" sender:self]; 
     } 
    } 
} 

而在MYItemViewController加载时,类似的流程。

if (_appDelegate.deepLinkId) { 
    MYItem *plate = [MYItem lookupById:_appDelegate.deepLinkId inManagedObjectContext:_appDelegate.dataDocument.managedObjectContext]; 
    NSIndexPath *indexPath = [self.fetchedResultsController indexPathForObject:plate]; 
    [self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionMiddle]; 

    _appDelegate.deepLinkId = nil; 
    [self performSegueWithIdentifier:@"ITEM_SEGUE" sender:self]; 
} 

我也不得不遵守UIApplicationDidBecomeActiveNotification的使用情况下,当应用程序已经打开。

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(processDeepLink) 
              name:UIApplicationDidBecomeActiveNotification 
              object:nil];