NSInternalInconsistencyException: There can only be one UIApplication instance

5.1k views Asked by At

Description:

Trying to open a Youtube URL in my application using the UIApplication class.

let url = URL(string: "https://www.youtube.com/watch?v=smOp5aK-_h0")!
let app = UIApplication()
if app.canOpenURL(url){
  //Crash here
  app.openURL(url)
}

Question:

Why does my application crash when I attempt to open the url?

Error:

* Assertion failure in -[UIApplication init], * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'There can only be one UIApplication instance.'

Edit: Does not crash but doesn't open the link:

       if UIApplication.shared.canOpenURL(url){
            print("Can open shared application url.")
            if #available(tvOS 10.0, *) {
                print("tvOS 10.0 detected")
                UIApplication.shared.open(url){res in
                    //res is false... 
                    print("Result..." + String(res))
                }
            } else {
                // Fallback on earlier versions
                UIApplication.shared.openURL(url)
            }
        }
2

There are 2 answers

6
Ahmad F On BEST ANSWER

The error is saying:

There can only be one UIApplication instance

Means that there is one instance should be called, when working with UIApplication it should be shared (singleton) instance. As mentioned in UIApplication's Documentation:

The UIApplication class provides a centralized point of control and coordination for apps running in iOS. Every app has exactly one instance of UIApplication (or, very rarely, a subclass of UIApplication). When an app is launched, the system calls the UIApplicationMain(::::) function; among its other tasks, this function creates a Singleton UIApplication object. Thereafter you access the object by calling the shared() class method.

shared():

All UIApplication notifications are posted by the app instance returned by shared().

So what do you need to is to change let app = UIApplication() to let app = UIApplication.shared:

let url = URL(string: "https://www.youtube.com/watch?v=smOp5aK-_h0")!
let app = UIApplication.shared
if app.canOpenURL(url) {
    app.open(url, options: [:], completionHandler: nil)
}

Or:

// for being safe, I suggest also to do "optional-binding" for the url:
if let url = URL(string: "https://www.youtube.com/watch?v=smOp5aK-_h0") {
    if UIApplication.shared.canOpenURL(url) {
        UIApplication.shared.open(url, options: [:], completionHandler: nil)
    }
}
0
gasho On

The error says it clearly. You have to use the default application. UIApplication.shared.canOpenURL(url)