iosobjective-c3dtouchquickactionuiapplicationshortcutitem

Correct way to handle application launching with quick actions


I am having a hard time figuring out how to get my quick actions working when I launch my app with a quick action.

My quick actions work, however, if the app was in the background and re-launched with the quick action.

When I try to launch the app straight from the quick action, the app opens as if it was launched by simply tapping the app icon (i.e. it does nothing).

Here is some code from my App Delegate.

In didFinishLaunchingWithOptions:

UIApplicationShortcutItem *shortcut = launchOptions[UIApplicationLaunchOptionsShortcutItemKey];
if(shortcut != nil){
    performShortcutDelegate = NO;
    [self performQuickAction: shortcut fromLaunch:YES];
}

The method called:

-(BOOL) performQuickAction: (UIApplicationShortcutItem *)shortcutItem fromLaunch:(BOOL)launchedFromInactive {
NSMutableArray *meetings = [self.fetchedResultController.fetchedObjects mutableCopy];
[meetings removeObjectAtIndex:0];
unsigned long count = meetings.count;
BOOL quickActionHandled = NO;
if(count > 0){
    MainViewController *mainVC = (MainViewController *)self.window.rootViewController;
    if(launchedFromInactive){
        mainVC.shortcut = shortcutItem;
    }
    else{
        UINavigationController *childNav;
        MeetingViewController *meetingVC;
        for(int i = 0; i < mainVC.childViewControllers.count; i++){
            if([mainVC.childViewControllers[i] isKindOfClass: [UINavigationController class]]){
                childNav = mainVC.childViewControllers[i];
                meetingVC = childNav.childViewControllers[0];
                break;
            }
        }

        self.shortcutDelegate = meetingVC;

        if ([shortcutItem.type isEqual: @"Meeting"]){
            NSNumber *index = [shortcutItem.userInfo objectForKey:@"Index"];
            [self.shortcutDelegate switchToCorrectPageWithIndex: index launchedFromInactive:NO];
            quickActionHandled = YES;
        }
    }
}

The only action that needs to be performed is that my page view controller (which is embedded inside the meetingVC) should switch to a certain page with respect to the shortcut chosen.

Any ideas on what causes the shortcut to not do anything when using it to launch as opposed to re-opening the app from the background??


Solution

  • I came to realize I was trying to call my methods on a view controller that was not in memory yet. This was causing bizarre behavior in my app. I did have the correct approach to getting access to the view controller and then it dawned on me the possibility of trying to execute the code using GCD.

    __block MeetingViewController *safeSelf = self;
    contentVC = [self initializeContentViewController: self.didLaunchFromInactive withPageIndex: intIndex];
    NSArray *viewControllers = @[contentVC];
    dispatch_async(dispatch_get_main_queue(), ^{
            [safeSelf.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
        });
    

    The above worked like magic, and the shortcuts are leading to the correct page. Using a similar approach to mine hopefully yields the desired results for anyone else who wanted to get their shortcuts working by launching the app.