iosswiftswift3corespotlightnsuseractivity

cannot trigger continueUserActivity in Swift 3 / iOS 10


Note: I figured most of this out - see the update at the end. Still some confusion.

I'm trying to implement NSUserActivity handling in Xc8b6 under Swift 3 and having trouble with the method signature for the handler protocol method.

In the current doc, the method is said to be:

func application(_ application: UIApplication, 
                 continue userActivity: NSUserActivity, 
       restorationHandler: @escaping ([Any]?) -> Void) -> Bool

This differs only slightly from what I see in the swift header interface. There, the return type in the restorationHandler is Swift.Void.

When I try this, the error I get is:

Objective-C method 'application:continue:restorationHandler:' provided by method 'application(_:continue:restorationHandler:)' does not match the requirement's selector ('application:continueUserActivity:restorationHandler:')

I realize the compiler warnings aren't great right now, but I take this to mean it's found the Obj-C method signature for this, but that somehow my arguments don't quite match.

I'm not sure where else to go with this. It matches what's there - but something is wrong. Random guessing and checking has not helped me yet.

Interestingly, autocomplete gives me a different method signature:

public func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: ([Any]?) -> Void) -> Bool

Nice thing about this one is that it compiles. Less nice thing is that it doesn't get triggered when I select an indexed item from Spotlight and tap it to launch the app.

Clearly my NSUserAction correctly identified the app and launched it. Is there something I could be missing here where it wouldn't fire off restorationHandler? Note this is converted from a project that ran fine under iOS 9.

I've also seen yet another version of the protocol method signature in the WWDC video on What's New With Search. I tried that, and it compiled but didn't trigger either.

Just to round things out, this is the signature I had after the Swift 3 conversion tool completed. It compiled, but didn't get triggered when launching from spotlight:

func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]) -> Void) -> Bool

----Update-----

Ok. So the first method signature mentioned above IS the correct one. The problem is that I was defining it in an extension to the AppDelegate. This worked fine in Swift 2.x.

I've moved it up, and everything is fine. But I would like to get a better understanding on why I get these compile errors when implementing a protocol method from an extension. Does it no longer carry thru the protocol conformance? If I try to add it onto the extension, I get an error indicating that it's a duplicate, so I don't think that's quite it.


Solution

  • The original question was about why continueUserActivity wasn't getting called (and what the correct signature was) so I'll answer that here adding some clarity on what went wrong.

    The correct signature is what I put at the top of my post:

    func application(_ application: UIApplication, 
                     continue userActivity: NSUserActivity, 
           restorationHandler: @escaping ([Any]?) -> Void) -> Bool
    

    Keep in mind this signature is DIFFERENT from what autocomplete provides in Xc8b6, so I suspect someone else might hit this and benefit from this response.

    My original issue is that it wasn't compiling because I was doing it from within an extension. For clarity:

    extension AppDelegate {
      func application(_ application: UIApplication,
                       continue userActivity: NSUserActivity,
                       restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
        return true
      }
    }
    

    This worked in any older iOS 9 / Swift 2.x project (with the older continueUserActivity signature). I'm still not positive why, but it won't compile in an extension in Xc8 / Swift 3.

    I moved it to the class scope and it works fine now.