2

I'm working on the Swift version of an app that handles custom URL schemes.

The method you need to implement changed in iOS 9.

The Objective-C version of the method works fine in an Objective-C app:

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary<NSString *,
                     id> *)options
{
  //my code here
}

However, in my Swift app, the equivalent function:

func application(application: UIApplication,
  openURL: NSURL,
  options: [String : AnyObject]) -> Bool
{
  //My code here
}

Is never called when I run the app on an iOS 9 device. When I invoke my custom URL scheme in Safari, I get prompted 'Open in "appname"?', and when I tap open, it brings my app back to the foreground, but the above method does not get called.

There must be some subtle mismatch in my method signature, but I can't see it. What am I doing wrong? I've tried various variations, none of which work.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • is your custom URL scheme has http or https protocol? – Nazariy Vlizlo Jan 08 '16 at 16:40
  • From Apple Developer : This method is not called if your implementations return false from both the application:willFinishLaunchingWithOptions: and application:didFinishLaunchingWithOptions: methods. Maybe you missed this ? https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/index.html?hl=ar#//apple_ref/occ/intfm/UIApplicationDelegate/application:openURL:options: – Zell B. Jan 08 '16 at 16:44
  • @ZellB, thanks for the suggestion but that's not it. My `didFinishLaunchingWithOptions:` is returning true – Duncan C Jan 08 '16 at 17:45
  • @bat, I am implementing a custom URL PROTOCOL, e.g. `myurl://parameters`. It's not using the HTTP or HTTPS protocols, but my own custom protocol. – Duncan C Jan 08 '16 at 17:48
  • @DuncanC let Xcode autocomplete, looks like it is wrong to me. The correct would be `func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {` – Leo Dabus Jan 08 '16 at 18:17
  • Autocomplete isn't working for some reason, and pasting your function definition in doesn't work either, nor does copying the function definition from the header of the UIApplicationDelegate protocol. Very strange. – Duncan C Jan 08 '16 at 18:54

2 Answers2

1

My problem appears to have been a red herring caused by a corrupted project. I created a new project file and copied the same code in and in the new project, application:openURL:options: is called correctly.

This is a very strange problem. If I delete "AppDelegate.swift" in the malfunctioning project and replace it with an AppDelegate.m/AppDelegate.h, then the application:openURL:options: is called correctly in the Objective-C version.

My suspicion is that there is an intermittent bug in Xcode that causes some projects to fail to cal your app delegate's application:openURL:options: when the app delegate in Swift.

If you are having the same problem you may want to create a new project, set up your info.plist, and copy over the application:openURL:options: method to see if the new project calls your method.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
0

Function signature (iOS9) is:

func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool

And if you want to test it working, just copy this into your app delegate:

func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool 
{
        print("Scheme: \(url.scheme)")
        print("Host: \(url.host)")
        print("Path: \(url.path)")
        print("Query String: \(url.query)")

        // DEBUG: get all key-value pairs in options also
        for (key, value) in options {
            print("Key: \(key), Value: \(value)")
        }
        return true
}

Also remember to add the "scheme" (app name) to your info.plist file. Call from Safari on the phone like this

scheme://host/path?query

Speedy99
  • 1,691
  • 15
  • 15