Открыть универсальную ссылку, когда приложение не в фоновом режиме

У меня аналогичный случай с этой проблемой iOS: универсальная ссылка Apple, если приложение не открыт? . Когда я нажимаю универсальную ссылку, приложение не может перейти в func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {}, если оно не находится в фоновом режиме.

Я добавил несколько кодов в файл didFinishLaunchingWithOptions. Однако это не работает. Большое спасибо Если кто-то может помочь.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    let activityDic = launchOptions?[UIApplicationLaunchOptionsKey.userActivityDictionary]
    if activityDic != nil {
        // Continue activity here
        self.window?.rootViewController?.restoreUserActivityState(activityDic as! NSUserActivity)
    }


   return true
}

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
    if userActivity.activityType == NSUserActivityTypeBrowsingWeb {          
            if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "xxx") as? XXXTableViewController {
                if let window = self.window, let rootViewController = window.rootViewController {
                    var currentController = rootViewController
                    while let presentedController = currentController.presentedViewController {
                        currentController = presentedController
                    }
                    currentController.present(controller, animated: true, completion: nil)
                }
            }
    }

    return true

}

person ray    schedule 08.03.2017    source источник


Ответы (6)


Поместите этот код в функцию didFinishLaunchingWithOptions, чтобы открывать URL-адрес при запуске приложения (код Swift 3):

    if let url = launchOptions?[UIApplicationLaunchOptionsKey.url] as? URL { //Deeplink
        // process url here
    }
    else if let activityDictionary = launchOptions?[UIApplicationLaunchOptionsKey.userActivityDictionary] as? [AnyHashable: Any] { //Universal link
        for key in activityDictionary.keys {
            if let userActivity = activityDictionary[key] as? NSUserActivity {
                if let url = userActivity.webpageURL {
                    // process url here
                }
            }
        }
    }
person Bogy    schedule 22.11.2017
comment
Идеальный!! Халяль олсун! - person ElvinM; 25.09.2018
comment
При каких условиях UIApplicationLaunchOptionsKey.url не будет нулевым? - person Will Calderwood; 18.07.2020

    if let activityDic = launchOptions?[UIApplicationLaunchOptionsUserActivityDictionaryKey] {

        let options = activityDic.allValues.filter({ (option:AnyObject) -> Bool in

            return option is NSUserActivity
        })

        if options.count > 0 , let userActivity = options[0] as? NSUserActivity{
            // User activity handling should be done here 

        }

    }

Используйте описанный выше метод, если вы не можете получить доступ к «userActivity» обычным способом.

person Ashish Jith    schedule 17.04.2017

Для IOS14 Swift 5 используйте файл SceneDelegate и функцию

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        // Get URL components from the incoming user activity.
        guard let userActivity = connectionOptions.userActivities.first,
              userActivity.activityType == NSUserActivityTypeBrowsingWeb,
              let incomingURL = userActivity.webpageURL
        else { return }
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            LinkHandler.sharedInstance.handleLink(url: incomingURL)
        }
        guard let _ = (scene as? UIWindowScene) else { return }
    }
person Dmih    schedule 23.10.2020

Вы можете получить доступ к URL-адресу в словаре параметров запуска, который передается вашему приложению во время инициализации. Пример реализации внутри метода AppDelegate application(_:didFinishLaunchingWithOptions:):

// Catch if open app from url
if let options = launchOptions {
    for key in options.keys {
        if(key == UIApplicationLaunchOptionsKey.url) {
            if let url = options[key] as? URL {
                AppDelegate.handleOpenURLWhenAppIsNotOpen(url)
            }
        }
    }
}

// or
if let url = launchOptions?[UIApplication.LaunchOptionsKey.url] as? URL {
    AppDelegate.handleOpenURLWhenAppIsNotOpen(url)
}

В AppDelegate вам нужен метод:

private class func handleOpenURLWhenAppIsNotOpen(_ url: URL) {
     //can make what you like
}
person Svetoslav Bramchev    schedule 08.03.2017
comment
Спасибо за ваш ответ. Я пытался, но он сказал, что у AppDelegate нет дескриптора члена OpenURLWhenAppIsNotOpen. Извините, если я напечатал это неправильно. - person ray; 08.03.2017
comment
handleOpenURLWhenAppIsNotOpen — это мой собственный метод, в котором вы можете написать все, что вам нравится (представить экран входа в систему или другой экран в приложении). В моем случае я запускаю tabBarController и выбираю одну из четырех вкладок. - person Svetoslav Bramchev; 09.03.2017

Я использовал Branch.io для обработки универсальной ссылки. Следующий код предназначен для справки, если кому-то нужно.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    //branch.io
    let branch: Branch = Branch.getInstance()
    branch.initSession(launchOptions: launchOptions, andRegisterDeepLinkHandler: {params, error  in
        // If the key 'pictureId' is present in the deep link dictionary
        if error == nil && params!["pictureId"] != nil {
            print("clicked picture link!")
            // load the view to show the picture
        } else {
            // load your normal view
        }
    })
    //branch io

    FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions) //don't put it on return
    return true
}

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
        // pass the url to the handle deep link call
        Branch.getInstance().continue(userActivity)

}
person ray    schedule 10.03.2017

Swift 4, 5 (рабочее решение)

Вы можете попробовать следующий фрагмент кода:

if let launchOptions = launchOptions, let dict = launchOptions[UIApplication.LaunchOptionsKey.userActivityDictionary] as? NSDictionary {
    if let userActivity = dict.first(where: { $0.value as? NSUserActivity != nil })?.value as? NSUserActivity {
       // handle your logic here
    }
}
person Hanry    schedule 02.10.2020