app launch via url (deep link) crashes if compiled with Xcode beta 6

anyone else having this issue? it's crashing for me both on device and simulator

Have you verified your UIApplicationDelegate methods match the new signatures? Beta 6 changed tons of method signatures in very subtle ways that the migrator won't fix for you. I noticed on several of my apps that the application delegate methods in particular were changed, but the only errors I got were stupid Fixits telling me to mark the methods as private or as @nonobjc. You can't do either of these things... you have to replace the method sigs with the new signatures.

I noticed on several of my apps that the application delegate methods in particular were changed, but the only errors I got were stupid Fixits telling me to mark the methods as private or as @nonobjc. You can't do either of these things... you have to replace the method sigs with the new signatures.

Indeed. The main difference is that closures are now considered non-escaping by default (SE-0103), so you have to mark escaping closure with

@escaping
. For example, this:
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void)

needs to be this:

func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void)

The fixit engine is not yet up to speed on this change. For that matter, neither is the code completion engine. You could file a bug about this but I’m willing to bet that the Xcode folks already know about it (-:

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks @karim and @eskimo for the hint - in my case it was caused by implementing this method:


@available(iOS, introduced: 4.2, deprecated: 9.0, message: "Please use application:openURL:options:")

optional public func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool


So I started using:

optional public func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool // no equiv. notification. return NO if the application can't open for some reason


And put this line above the previous method:


@available(iOS, introduced: 2.0, deprecated: 9.0)

And now it doesn't crash anymore

thanks everyone

@karim @eskimo

already checked the signatures which are correct but thanks for pointing it out as it somehow helped

@hyou


didn't know that the previous was deprecated (missed the warning if there was any I guess),

so I added also the second method which did solve partially, as you can immagine the issue appears now only on devices with iOS < iOS 9.0


I guess it is related to latest changes they made to Swift <--> Objective-C objects importing, as it was working till beta 5 ,

Using Xode 8.0 beta 6, my iOS app (deployment target = 8.4) had a similar issue:


Existing implementation (in app delegate):

func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
     // ...
}


This worked fine until I compiled it for iOS 10 (it was deprecated in iOS 9.0). Now any 9.x or 10.x devices running this build will crash when handed an URL.


As mentioned in this thread, adding the new UIAppDelegate method seems to resolve the issue for those devices:

@available(iOS 9.0, *)
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
     // ...

}


It was my understanding, however, that deprecated methods (like the pre-iOS 9 one) would continue to work. Could this be an issue with this beta toolchain? Since my app can deploy to iOS 8.4, I assume my only option is to have both delegate methods in place, like this:

func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
     // ...

}

@available(iOS 9.0, *)
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
     // ...

}


Edit: I just tried it on the 8.4 simulator (I don't have a 8.4 device handy) and it crashes even if I have the two methods present (even if I take out the @available line). I doubt this is the intended behaviour. Note that I am using Swift 3.


Regards,


BB

I doubt this is the intended behaviour.

Indeed. This looks like fallout from SE-0116 Import Objective-C id as Swift Any type. I was able to work around it by:

  • declaring my method to use

    AnyObject
    rather than
    Any
  • using

    @objc(***)
    to tell Swift exactly what selector to use

To wit:

@objc(application:openURL:sourceApplication:annotation:) func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: AnyObject) -> Bool {
    NSLog("url: %@", url as NSURL)
    return true
}

This is using Xcode 8.0b6. I’d appreciate someone filing a bug about this, then posting the bug number here, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks Quinn.


I just created bug #28074688 regarding this issue.

I doubt that the Xcode folks already know about all the consequences of SE-0103. I filed bug 27865533 more than two weeks ago,with no reaction so far, and figured out only recently that it is due to a partial implementation of SE-0103: closures passed as function parameters are considered non-escaping, but typealiased closures are considered escaping. The following code illustrates this:


typealias BasicClosure = () -> ()
class MyClass: NSObject
{
    var aliasedDict: [String: BasicClosure] = [:]
    var explicitDict: [String: () -> ()] = [:]

    func aliasedFunc(_ string:String, closure:BasicClosure) {
        aliasedDict[string] = closure
        explicitDict[string] = closure
    }

    func escapingFunc(_ string:String, closure:@escaping () -> ()) {
        aliasedDict[string] = closure
        explicitDict[string] = closure
    }

    func explicitFunc(_ string:String, closure:() -> ()) {
        aliasedDict[string] = closure
        // compiler error: cannot assign value of type '() -> ()' to type 'BasicClosure?'
        explicitDict[string] = closure
        // compiler error: cannot assign value of type '() -> ()' to type '(() -> ())?'
    }
}


@escaping also destroys the Quick Help functionality of Xcode: aliasedFunc and explicitFunc are documented, escapingFunc is not.


The Swift 3 Edition of the book "The Swift Programming Language" has not been updated, either. It keeps talking about @noescape but does not mention @escaping closures, and says several times that you can use the typealias anywhere you might use the original.


I hope the difference is not intentional. A type alias should not change code behaviour. The difference between an implicitly escaping typealiased closure and implicitly nonescaping explicit closure escapes any sane mind.


Objective-C has nothing to do with this.

It looks like this has been addressed in 10.0.1 GM (14A403). I can now compile and run the app with only the old delegate method on both iOS 8.4 (only tested with simulator) and iOS 10.


func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
    // ...
}
app launch via url (deep link) crashes if compiled with Xcode beta 6
 
 
Q