2

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.

jeffro37
  • 696
  • 6
  • 16
  • When adding a function to a protocol extension then it is equivalent to adding the function inside the original protocol definition. That is why you get an error that it is a duplicate. If the protocol extension is only for a specific type then it is a different story – user1046037 Sep 03 '16 at 05:27
  • It wasn't a protocol extension. I probably should just create a new question because my old one was answered and I now have a new one. Briefly - the extension is just: extension AppDelegate { So I'm extending the class, but not the protocol. – jeffro37 Sep 03 '16 at 14:43

2 Answers2

2

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.

jeffro37
  • 696
  • 6
  • 16
  • I have encouter the same problem with any optional method of AppDelegate. They do not build anymore in extensions.. This is very very annoying and makes the AppDelegate super dirty. I think it could be that the func have a scope like fileprivate? so extensions are not able to see them – Marco Pappalardo Oct 04 '16 at 14:18
  • @jeffro37 Your signature is giving me errors. Using Swift 4. – Jonny Nov 28 '17 at 08:17
0

So, it looks like that starting from Swift 3, protocol methods are only accessible in the scope where the protocol is attached to a class.

this means that all the method of AppDelegate that are inside the protocol UIApplicationDelegate are only accessible in the class AppDelegate or in the extension of AppDelegate which conforms to UIApplicationDelegate

If you try to access a method of UIApplicationDelegate outside of that class/extension that is conforming to UIApplicationDelegate you will not be able to compile.

Marco Pappalardo
  • 935
  • 6
  • 23