iosobjective-chandoffnsuseractivity

ios Handoff missing NSUserActivity in launchOptions?


I have implemented Handoff in our App and it is working fine for web to app handoff and vice versa, when the app is running in foreground or in the background.

However if the app is not running, then if the user launches the app from a web to app handoff, in the launchOptions dictionary, I get the UIApplicationLaunchOptionsUserActivityDictionaryKey, but the reference to the activity is missing.

See screenshot:

enter image description here

As you can see I'm getting only the ID for the NSUserActivity. Is this a bug in iOS 9 ?

Is there a way to get a reference to the activity by using the id?

Edit, here is the code, although I don't think this is relevant

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    if (launchOptions && [[launchOptions allKeys] containsObject:UIApplicationLaunchOptionsUserActivityDictionaryKey]) {
        __block NSUserActivity *activity;

        NSDictionary *userActivityDictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsUserActivityDictionaryKey];
        if (userActivityDictionary) {
            [userActivityDictionary enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
                if ([obj isKindOfClass:[NSUserActivity class]]) {
                    activity = obj;
                }
            }];
        }

        //app was started by URL (deep linking), check parameters
        if (activity) {
            NSURL *url = activity.webpageURL;
            //resume from URL
        }
    }

    return YES;
}

Solution

  • Ok,

    I've submitted a TSI about this to Apple, and it seems that this is not a bug, but by design.

    You can resume your activity in the application:continueUserActivity:restorationHandler delegate, which in my case was not called.

    Well, my mistake was that you need to return YES in the application:didFinishLaunchingWithOptions: method, else if you return NO, the application:continueUserActivity:restorationHandler is not called.

    We had implemented FB in our app, so we where returning [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions] which would return NO.

    I have changed our code in the application:didFinishLaunchingWithOptions: function to this

    if (launchOptions && [[launchOptions allKeys] containsObject:UIApplicationLaunchOptionsUserActivityDictionaryKey]) {
            return YES;
        }
    else {
            return [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
    }
    

    This way the application:continueUserActivity:restorationHandler delegate is being successfully called and the activity can be resumed successfully.