Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method 'scene(_:openURLContexts:)' is not called

In the info.plist file I configured URL Identifier and URL Scheme successfully. Also I am able to open the app using the custom URL. The problem is when the app launches for the first time, the method

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) 

does not get called.

I have some dependent functionality based on the above method. So when the app launches for the first time, I am not able to see anything in my app.

Also I added code in the method

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        
        guard let _ = (scene as? UIWindowScene) else { return }
        
        let url = connectionOptions.urlContexts.first?.url
        
    }

but I get url as nil here.

However if my app is in background mode and I hit URL then above method calls successfully and dependent functionality working fine. Following is my code on scene(_:openURLContexts:) method in sceneDelegate.

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>){
        let url = URLContexts.first?.url
        let urlString: String = url!.absoluteString
        
        if let urlComponents = URLComponents(string: urlString),let queryItems = urlComponents.queryItems {
            queryParams = queryItems
        } else {
            print("invalid url")
        }
        
        guard let windowScene = (scene as? UIWindowScene) else { return }


        self.window = UIWindow(windowScene: windowScene)
        //self.window =  UIWindow(frame: UIScreen.main.bounds)

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        guard let rootVC = storyboard.instantiateViewController(identifier: "LocationViewIdentifier") as? UIViewController else {
            print("ViewController not found")
            return
        }
        let rootNC = UINavigationController(rootViewController: rootVC)
        self.window?.rootViewController = rootNC
        self.window?.makeKeyAndVisible()
    }

Can anyone tell me why first time above method does not call?

like image 713
iPhone Avatar asked Nov 21 '19 10:11

iPhone


3 Answers

Maybe this will help your situation.


func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
       
    let urlinfo = connectionOptions.urlContexts
    let url = urlinfo.first?.url as! NSURL
  
}

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext*h>) {
       
    let url = URLContexts.first!.url as NSURL

}

Update at 17.6.2021

If you wish to use Deeplink and Universal Link both this is my method.

    //Deeplink or Universial Link Open when app is start.
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
                
        // Universial link Open
        if let userActivity = connectionOptions.userActivities.first,
           userActivity.activityType == NSUserActivityTypeBrowsingWeb,
           let urlinfo = userActivity.webpageURL{
            
            print ("Universial Link Open at SceneDelegate on App Start ::::::: \(urlinfo)")
            
        }
        
        //deeplink Open
        if connectionOptions.urlContexts.first?.url != nil {
          let urlinfo = connectionOptions.urlContexts.first?.url
            
            print ("Deeplink Open at SceneDelegate on App Start ::::::: \(String(describing: urlinfo))")

          
        }
        
        guard let _ = (scene as? UIWindowScene) else { return }
    }

    // Universial link Open when app is onPause
    func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
        
        if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
            let urlinfo = userActivity.webpageURL{
            
            print ("Universial Link Open at SceneDelegate on App Pause  ::::::: \(urlinfo)")
            
        }
    }
    
    // Deeplink Open when app in onPause
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        
        let urlinfo = URLContexts.first?.url
        print ("Deeplink Open on SceneDelegate at App Pause :::::::: \(String(describing: urlinfo))")

    }

Thanks

like image 200
Peterworks Avatar answered Oct 20 '22 16:10

Peterworks


I had the same problem, and the method scene(_ scene:, continue userActivity:) was only called when the app is open.

When I checked the connectionOptions passed to the method scene(_ scene:, willConnectTo session, options connectionOptions:) it had a user activity with the expected URL. So, I ended up calling the first method manually:

func scene(_ scene: UIScene,
           willConnectTo session: UISceneSession,
           options connectionOptions: UIScene.ConnectionOptions) {

    if let userActivity = connectionOptions.userActivities.first {
        self.scene(scene, continue: userActivity)
    }
}
like image 31
Hejazi Avatar answered Oct 20 '22 15:10

Hejazi


I think the Apple docs explain it most clearly, i.e.,

If your app has opted into Scenes, and your app is not running, the system delivers the URL to the scene(_:willConnectTo:options:) delegate method after launch, and to scene(_:openURLContexts:) when your app opens a URL while running or suspended in memory.

Hence, it would only call your scene(_:openURLContexts:) (i.e., the one with this signature: func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) in the question) when your app opens a URL while running or suspended in memory only.

Instead, when the app is launched the first time, it calls scene(_:willConnectTo:options:).

like image 4
auspicious99 Avatar answered Oct 20 '22 16:10

auspicious99