Используете встроенную глубокую ссылку Facebook iOS и openURL с приложением на основе раскадровки/перехода iOS 5?

У меня есть приложение для iOS 5 с поддержкой Facebook, которое использует навигацию на основе раскадровки и перехода, и я не понимаю, как реализовать «собственную глубокую ссылку iOS». Пример кода на странице Улучшение распространения приложений на iOS просто отображает UIAlertView, но я пытаюсь инициировать две последовательные операции.

Для ответа на этот вопрос я упростил приложение до трех контроллеров представления: MYCategoryTableViewController, MYItemsTableViewController и MYItemViewController. В обычном потоке приложение открывается на MYCategoryTableViewController, в котором отображается таблица категорий. Когда пользователь выбирает категорию, происходит переход к MYItemsTableViewController, который отображает таблицу элементов для этой выбранной категории. Наконец, когда элемент выбран, есть переход к MYItemViewController, который отображает подробное представление элемента.

prepareForSegue из MYCategoryTableViewController устанавливает свойство целевого контроллера представления, которое представляет эту категорию:

- (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;
    }
}

prepareForSegue из MYItemsTableViewController устанавливает свойство целевого контроллера представления, которое представляет эту категорию:

- (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-адрес предоставляет идентификаторы для поиска объектов MYCategory и MYItem. Я нашел 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];
}

Обновление: Выбор программно ячейка в табличном представлении не выполняет связанный переход дала мне идею. Может быть, я просто сохраню URL-адрес из application:openURL: и позволю MYCategoryTableViewController загружаться естественным образом. Затем во время viewWillAppear позвоните tableView selectRowAtIndexPath, а затем performSegueWithIdentifier, чтобы перейти к MYItemsTableViewController. Повторите тот же шаблон в MYItemsTableViewController, но очистите URL перед вызовом performSegueWithIdentifier.


person Kevin Hakanson    schedule 28.05.2012    source источник


Ответы (1)


Вот что у меня получилось. В 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];
person Kevin Hakanson    schedule 08.06.2012