Firebase Deeplink not trigger application:continueUserActivity:restorationHandler, Swift 4.2 Xcode10. - ios

I followed all the steps from Firebase Dynamic Links documentation.
The Associated Domains is active and domain is already added also I add URL Schemes inside the info tab and programmatically inside the launchOptions function.
Deep link is opening the app but the only method triggered after clicking on dynamic link is willContinueUserActivityWithType which returning nil userActivity
In documentation mentioned continueUserActivity have to trigger if app is running on background but in my case not happening and I could find any other way to reed deep link data.
Here is my AppDelegate code:
import UIKit
import Firebase
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let options = FirebaseOptions(contentsOfFile: filePath)
options?.deepLinkURLScheme = "com.example"
FirebaseApp.configure(options: options!)
.
.
.
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
print("applicationDidBecomeActive")
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
func application(_ application: UIApplication, willContinueUserActivityWithType userActivityType: String) -> Bool {
if let incomigURL = userActivity?.webpageURL{
let linkHandle = DynamicLinks.dynamicLinks().handleUniversalLink(incomigURL) { (dynamiclink, error) in
if let dynamiclink = dynamiclink, let _ = dynamiclink.url {
self.handleIncomingDynamicLink(dynamicLink: dynamiclink)
} else {
print("willContinueUserActivityWithType | dynamiclink = nil")
}
}
return linkHandle
}
print("willContinueUserActivityWithType | userActivity = nil")
return false
}
func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
if let incomigURL = userActivity.webpageURL{
let linkHandle = DynamicLinks.dynamicLinks().handleUniversalLink(incomigURL) { (dynamiclink, error) in
if let dynamiclink = dynamiclink, let _ = dynamiclink.url {
self.handleIncomingDynamicLink(dynamicLink: dynamiclink)
} else {
print("continueUserActivity | dynamiclink = nil")
}
}
return linkHandle
}
print("continueUserActivity = nil")
return false
}
#available(iOS 9.0, *)
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any]) -> Bool {
return application(app, open: url,
sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
annotation: "")
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
print("Handle deep link.")
return true
}
func handleIncomingDynamicLink(dynamicLink: DynamicLink){
print("Your dynamic link parameter is = \(String(describing: dynamicLink.url))")
}
}

In swift 4.2 change the instant method to:
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool
So for handling Firebase deep link NSUserActivity function have to be like this:
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if let incomigURL = userActivity.webpageURL{
let linkHandle = DynamicLinks.dynamicLinks().handleUniversalLink(incomigURL) { (dynamiclink, error) in
if let dynamiclink = dynamiclink, let _ = dynamiclink.url {
self.handleIncomingDynamicLink(dynamicLink: dynamiclink)
} else {
print("dynamiclink = nil")
}
}
return linkHandle
}
print("userActivity = nil")
return false
}
Special thanks to user1376400

Are you using the same team ID profile you mentioned in app association file
{"appID":"TeamID","paths":["/*"]}]} in your application.
Check your domain name match with Associated Domains applink.
Validate your apple-app-site-association using some validator https://branch.io/resources/aasa-validator/

Related

After opening iOS app "continue userActivity:" method isn't called - Firebase dynamic link

I have successfully integrated Firebase dynamic links and when I click on dynamic link then my app is opening.
The issues I'm facing is after opening app from dynamic links, continue userActivity: method should be called, but nothing happens.
I've checked the all the possible thing but didn't recognised the issue.
I've searched the SO for this but none of the answer helped me.
My Code:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
GIDSignIn.sharedInstance().clientID = kGoogleSignInClientId
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
// DynamicLinks.performDiagnostics(completion: nil)
FirebaseApp.configure()
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
if url.absoluteString.contains(kFBAppId) {
return FBSDKApplicationDelegate.sharedInstance().application(app, open: url, options: options)
}
if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url) {
print(dynamicLink.url ?? URL(string: "test") as Any)
return true
}
return GIDSignIn.sharedInstance().handle(url, sourceApplication: options[.sourceApplication] as? String, annotation: options[.annotation])
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
//This method is not getting called
}
Additional answer for those using separate SceneDelegate.swift apart from AppDelegate.swift:
This method in AppDelegate >
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if userActivity.activityType == CSSearchableItemActionType {
}
is now in SceneDelegate >
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
}
I don't know whether they keep their doc. up to date or not.
I have just copy-pasted the code from the Google's official Firebase dynamic link document.
Why was the continue userActivity: method is not called?
The reason is (See the difference in following method)
Copy pasted from google doc. - Wrong one
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
}
I wrote this (without copy paste from google doc.) - Correct one
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([Any]?) -> Void) -> Bool {
}
I've made bold the difference.
This is what I was trying for many hours. It is really very frustrating for me to blindly trust on google doc.:-|
Hope this may help other.
You need to check two times.
When app. is running in the background and is opening from Link:
Delegate method is:func checkForTransferedTicket(_ userActivity: NSUserActivity) { }
When app. is NOT running in background and is opening from Link:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,options connectionOptions: UIScene.ConnectionOptions) { if let userActivity = connectionOptions.userActivities.first {
print(userActivity)
}
}

Swift Firebase Notifications "libc++abi.dylib: terminating with uncaught exception of type NSException"

I am trying to add Firebase Notifications to my app. I am getting a error before my app even starts. Also, whats the difference between calling notifications from my app vs Firebase? Is it not possible to call notifications from my app which is why firebase notifications is needed? I am very ignorant on notifications and a simple summary would be great. Thanks
import UIKit
import Firebase
import GoogleSignIn
import FBSDKCoreKit
import TwitterKit
import IQKeyboardManagerSwift
import OAuthSwift
import UserNotifications
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
var window: UIWindow?
static var shared: AppDelegate { return UIApplication.shared.delegate as! AppDelegate }
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
GIDSignIn.sharedInstance().delegate = self
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
IQKeyboardManager.sharedManager().enable = true
Twitter.sharedInstance().start(withConsumerKey: "6nQtUKZChHOJ0iNjUsHuJoMrH", consumerSecret: "CEEfZPMx4BSNel4eknivDCHALrWpxR5NBpjgtxmYxzFipTPJcz")
FirebaseApp.configure()
application.registerForRemoteNotifications()
requestNotificationAuthorization(application: application)
if let userInfo = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] {
NSLog("[RemoteNotification] applicationState: \(applicationStateString) didFinishLaunchingWithOptions for iOS9: \(userInfo)")
//TODO: Handle background notification
}
return true
}
var applicationStateString: String {
if UIApplication.shared.applicationState == .active {
return "active"
} else if UIApplication.shared.applicationState == .background {
return "background"
}else {
return "inactive"
}
}
func requestNotificationAuthorization(application: UIApplication) {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(options: authOptions, completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
}
// The callback to handle data message received via FCM for devices running iOS 10 or above.
#objc(applicationReceivedRemoteMessage:) func application(received remoteMessage: MessagingRemoteMessage) {
print(remoteMessage.appData)
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
let isFBOpenUrl = FBSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
let isGoogleOpenUrl = GIDSignIn.sharedInstance().handle(url, sourceApplication: sourceApplication, annotation: annotation)
if isFBOpenUrl { return true }
if isGoogleOpenUrl { return true }
return false
}
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
if (url.host == "oauth-callback") {
OAuthSwift.handle(url: url)
}
return Twitter.sharedInstance().application(app, open: url, options: options)
return true
}
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
// ...
if error != nil {
// ...
return
}
guard let authentication = user.authentication else { return }
let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken, accessToken: authentication.accessToken)
// ...
}
func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
// Perform any operations when the user disconnects from app here.
// ...
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
#available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
// iOS10+, called when presenting notification in foreground
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
NSLog("[UserNotificationCenter] applicationState: \(applicationStateString) willPresentNotification: \(userInfo)")
//TODO: Handle foreground notification
completionHandler([.alert])
}
// iOS10+, called when received response (default open, dismiss or custom action) for a notification
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
NSLog("[UserNotificationCenter] applicationState: \(applicationStateString) didReceiveResponse: \(userInfo)")
//TODO: Handle background notification
completionHandler()
}
}
extension AppDelegate : MessagingDelegate {
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
NSLog("[RemoteNotification] didRefreshRegistrationToken: \(fcmToken)")
}
// iOS9, called when presenting notification in foreground
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
NSLog("[RemoteNotification] applicationState: \(applicationStateString) didReceiveRemoteNotification for iOS9: \(userInfo)")
if UIApplication.shared.applicationState == .active {
//TODO: Handle foreground notification
} else {
//TODO: Handle background notification
}
}
}
Remove reference of your "GoogleService-Info.plist" file and again add it using add to file option...
for more watch it carefully
In my case it's due to i call FirebaseApp.configure() twice cause the problem. Hope it help to someone.
If your FirebaseApp.configure() is after you create your root view controller programmatically in the AppDelegate you get this same crash. Firebase needs to get setup before it gets called in that root VC.
Correct Setup:
FirebaseApp.configure()
// View Controller Setup
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
let mainViewController = ViewController()
mainViewController.view.backgroundColor = .black
window?.rootViewController = UINavigationController(rootViewController: mainViewController)

appflayer deeplinking not working when application open from link (delegate method not called)

I have deeplinking with AppFlayer SDK and universal link open the application successfully means deeplinking working fine.
Now issue is that when application open from link then it will not redirect to it's page. But if I put application in background and take in foreground then deeplinking works
I follow this guide lines.(link)
AppFlayer setup code
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
AppsFlyerTracker.shared().appsFlyerDevKey = "xxxxxxxxxxxx"
AppsFlyerTracker.shared().appleAppID = "xxxxxxx"
AppsFlyerTracker.shared().isDebug = false
AppsFlyerTracker.shared().delegate = self
self.pushNotificationService(application)
objStoryBoard = UIStoryboard(name:"Main", bundle: nil)
return true
}
AppFlayer delegate
Edit :: This method not called when application is open from link of appsflayer marketing
//MARK:
//MARK: appflayer delegate
func onAppOpenAttribution(_ installData: [AnyHashable: Any]) {
NSLog("installData ::%#", installData )
if let link = installData["link"] as? String
{
if link.contains(read_Localizable("titleAppflayer"))
{
if let arrQueryItems = URLComponents(string: link)!.queryItems {
for obj in arrQueryItems {
if obj.name.caseInsensitiveCompare(read_Localizable("appflayerParameter")) == .orderedSame
{
self.redirectAppflayer(withstrUrl: obj.value!)
return
}
}
}
}
}
}
user activity method of application
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: #escaping ([Any]?) -> Void) -> Bool {
// if let url = userActivity.webpageURL
// {
// NSLog("URL :: %#",[url])
// }
if userActivity.webpageURL?.absoluteString.contains(read_Localizable("titleAppflayer")) == true
{
AppsFlyerTracker.shared().continue(userActivity, restorationHandler: restorationHandler)
return true
}
return Branch.getInstance().continue(userActivity)
}
Let me know what i doing wrong.
You are calling the AppsFlyerTracker from willFinishLaunchingWithOptions when it should be called from didFinishLaunchingWithOptions. Could you move the relevant code and test again?
Add
[[AppsFlyerTracker sharedTracker] trackAppLaunch];
onConversionDataSuccess method will start getting call.

Swift 3: Ambiguous reference to member 'subscript' while using UberRides SDK

I'm currently developing an iOS application using Swift 3 and the UberRides SDK. According to their docs, the AppDelegate class needs to be modified to contain the following:
UberRides SDK AppDelegate information
I did so, and here's the code I have:
import UIKit
import UberRides
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Handle incoming SSO Requests
RidesAppDelegate.sharedInstance.application(application, didFinishLaunchingWithOptions: launchOptions)
// Other logic
return true
}
#available(iOS 9, *)
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
let handledURL = RidesAppDelegate.sharedInstance.application(app, openURL: url as URL, sourceApplication: options[UIApplicationOpenURLOptionsSourceApplicationKey] as? String, annotation: options[UIApplicationOpenURLOptionsAnnotationKey])
if (!handledURL) {
// Other URL parsing logic
}
return true
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
let handledURL = RidesAppDelegate.sharedInstance.application(application, openURL: url as URL, sourceApplication: sourceApplication, annotation: annotation)
if (!handledURL) {
// Other URL parsing logic
}
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
However, I am getting the error: "Ambiguous reference to member 'subscript'" in this function, specifically at "options[UIApplicationOpenURLOptionsSourceApplicationKey]":
func application(app: UIApplication, openURL url: NSURL, options: [String : AnyObject]) -> Bool {
let handledURL = RidesAppDelegate.sharedInstance.application(app, openURL: url as URL, sourceApplication: options[UIApplicationOpenURLOptionsSourceApplicationKey] as? String, annotation: options[UIApplicationOpenURLOptionsAnnotationKey])
if (!handledURL) {
// Other URL parsing logic
}
return true
}
I am very new to Swift, and am not really sure as to how to go about solving this issue! Any help would be appreciated. Thanks!

iPhone freeze when using QuickActionItems

I have added 3D Touch on my app icon to show Quick Action menu. I think I should have it all set up correctly.
The problem is that when I am choosing one of the items in the Quick Action menu, the iPhone freezes for a few seconds before it opens up the application.
This is my AppDelegate.swift:
import UIKit
import Parse
#available(iOS 9.0, *)
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
Parse.setApplicationId("xx",
clientKey: "xx")
let currentInstallation: PFInstallation = PFInstallation.currentInstallation()
currentInstallation.badge = 0
currentInstallation.saveEventually()
return true
}
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
let rootNavigationViewController = window!.rootViewController as? UINavigationController
let rootViewController = rootNavigationViewController?.viewControllers.first as UIViewController?
rootNavigationViewController?.popToRootViewControllerAnimated(false)
if shortcutItem.type == "JEGHARALDRI" {
rootViewController?.performSegueWithIdentifier("JEGHARALDRISEGUE", sender: nil)
}
if shortcutItem.type == "PLING" {
rootViewController?.performSegueWithIdentifier("PLINGSEGUE", sender: nil)
}
if shortcutItem.type == "FLASKETUTENPEKERPƅ" {
rootViewController?.performSegueWithIdentifier("FLASKETUTENPEKERPƅSEGUE", sender: nil)
}
if shortcutItem.type == "KORTETTALER" {
rootViewController?.performSegueWithIdentifier("KORTETTALERSEGUE", sender: nil)
}
}
}
I think your app delegate should more looks like something like this
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
//MARK: - Properties
var window: UIWindow?
lazy var quickActionManager: QuickActionsManager = {
return QuickActionsManager()
}()
//MARK: - AppDelegate Methods
func application(application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
{
return self.setupQuickActions(launchOptions)
}
func application(application: UIApplication, performActionForShortcutItem
shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void)
{
completionHandler(self.quickActionManager.handleShortcut(shortcutItem))
}
//MARK: - Private Methods
private func setupQuickActions(launchOptions: [NSObject: AnyObject]?) -> Bool
{
guard let shortcutItem = launchOptions?[UIApplicationLaunchOptionsShortcutItemKey]
as? UIApplicationShortcutItem else { return false }
return self.quickActionManager.handleShortcut(shortcutItem)
}
}
And so then you get all the logic to handle a quick action in your quick action manager, which would looks something like this
//MARK: - Public Methods
func handleShortcut(shortcut: UIApplicationShortcutItem?) -> Bool
{
guard let shortcut = shortcut else { return false }
// Get the key of the shortcutItem
let key = self.shortKeyForType(shortcut.type)
// Check if that key is the key of a knowed viewController
guard let viewControllerKey = ViewControllerKeys(rawValue: key) else { return false }
// Try to show This View Controller
return self.showViewController(viewControllerKey)
}
Assuming you got an enum of viewController to display matching each quick actions.
I hope this answer your question, let me know if you got some more.

Resources