How to call a view controller via Quick Actions (3D touch) Swift - ios

I'm trying to implement a 3D touch command where if the user presses "New scan", then the view controller ProcessedImageViewController is called. I have already set up the Info.plist to create the quick option, but I am having trouble actually calling the ProcessedImageViewController when "New scan" is pressed.
Here is my code from the AppDelegate.swift:
var launchedShortcutItem: UIApplicationShortcutItem?
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
if let shortcutItem = launchOptions?[UIApplication.LaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem{
launchedShortcutItem = shortcutItem
}
return true
}
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: #escaping (Bool) -> Void) {
completionHandler(handleShortcutItem(item: shortcutItem))
}
func applicationDidBecomeActive(_ application: UIApplication) {
guard let shortcutItem = launchedShortcutItem else { return }
//If there is any shortcutItem,that will be handled upon the app becomes active
_ = handleShortcutItem(item: shortcutItem)
//We make it nil after perfom/handle method call for that shortcutItem action
launchedShortcutItem = nil
}
func handleShortcutItem(item: UIApplicationShortcutItem) -> Bool {
var handled = false
// Verify that the provided shortcutItem's type is one handled by the application.
let mainStoryboard = UIStoryboard.init(name: "Main", bundle: Bundle.main)
var reqVC: UIViewController!
reqVC = mainStoryboard.instantiateViewController(withIdentifier: "ProcessedImageViewController") as! ProcessedImageViewController
handled = true
if let homeVC = self.window?.rootViewController as? UINavigationController {
homeVC.pushViewController(reqVC, animated: true)
} else {
return false
}
return handled
}
When I try to click on "New scan" in the Quick Actions menu, I only get taken to the Root View controller (not ProcessedImageViewController).

Related

Unable to read deeplink URL in AppDelegate method (swift 4, iOS 13)

I'm trying deeplink to open particular page in app on click of shared link from other app/from safari, URL opens the app but unable to take application on particular page i,e, unable to read link (custom URL). This is my custom URL :- WOT://tradeDetail
If anyone knows where i'm going wrong, please help
here is screenshot and code
var window: UIWindow?
var scheme = "WOT"
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
GMSPlacesClient.provideAPIKey(WOT.googlePlaceAPIKey)
if let url = launchOptions?[.url] as? URL {
return handle(url: url)
}
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return handle(url: url)
}
func handle(url: URL) -> Bool {
switch url.absoluteString {
case "\(scheme)://tradeDetail" : do {
let sb = UIStoryboard(name: "Main", bundle: .main)
let detailView = sb.instantiateViewController(withIdentifier: "SearchedPlaceDetailVC") as? SearchedPlaceDetailVC
window?.rootViewController = detailView
window?.makeKeyAndVisible()
}
default: return false
}
return true
}
You need to call below function to navigate particular page
func application(_ application: UIApplication, continue userActivity:
NSUserActivity, restorationHandler: #escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
let myUrl: String? = userActivity.webpageURL?.absoluteString
if myUrl?.range(of: "tradeDetail") != nil {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let yourViewController = storyboard.instantiateViewController(withIdentifier: “YourViewController”) as? YourViewController
self.window?.rootViewController = yourViewController
self.window?.makeKeyAndVisible()
}
return true
}

3D Touch quick actions not working when called from didFinishLaunchingWithOptions

I'm implementing 3D touch quick actions in my app and I have the following problem:
When the app is already running and so the quick action is initiated through perform Action For Shortcut Item, it works perfectly fine. However, when the app is killed and then launched through a quick action (so didFinishLaunchingWithOptions) it does not take me to the desired view controller, but rather to the home screen of the app.
Here is my code:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//... other stuff I'm doing
if let shortcutItem = launchOptions?[UIApplication.LaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem {
shortcutItemToProcess = shortcutItem
}
return true
NOTE: I've read previous SO answers where they said that I need to return false in didFinishLaunchingWithOptions when the app was launched through a quick action, so that performAction won't get called. I need to always return true however in my didFinishLaunching method because of the other things I'm handling there. I tried however to return false just to see if that causes the problem and the app still behaved the same way.
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: #escaping (Bool) -> Void) {
shortcutItemToProcess = shortcutItem
}
Here is how I present the view controller:
func applicationDidBecomeActive(_ application: UIApplication) {
if let shortcutItem = shortcutItemToProcess {
if shortcutItem.type == "com.myName.MyApp.myQuickAction" {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let myViewController = storyboard.instantiateViewController(withIdentifier: "myViewController") as! MyViewController
if let navVC = window?.rootViewController as! UINavigationController? {
navVC.pushViewController(myViewController, animated: true)
}
}
So this works fine when app is already running, but it lands me on the home page of my app when the app is killed. What am I doing wrong and how can I solve this?

Static 3D Touch not showing navigation and tab bar after lunching

3D Touch is working fine when I press it on the home screen, but not showing the navigation and tab bar, How can I present Navigation and Tab bar using 3D Touch? Don't know how to Override point for customization after application launch.
Grazie Mille
class AppDelegate: UIResponder, UIApplicationDelegate {
enum ShortcutIdentifier: String {
case First
case Second
case Third
case Fourth
//Initializers
init?(fullType: String) {
guard let last = fullType.components(separatedBy: ".").last else { return nil }
self.init(rawValue: last)
}
//Properties
var type: String {
return Bundle.main.bundleIdentifier! + ".\(self.rawValue)"
}
}
var window: UIWindow?
/// Saved shortcut item used as a result of an app launch, used later when app is activated.
var launchedShortcutItem: UIApplicationShortcutItem?
func handleShortCutItem(_ shortcutItem: UIApplicationShortcutItem) -> Bool {
var handled = false
// Verify that the provided shortcutItem type is one handled by the application.
guard ShortcutIdentifier(fullType: shortcutItem.type) != nil else { return false }
guard let shortCutType = shortcutItem.type as String? else { return false }
let storyboard = UIStoryboard(name: "Main", bundle: nil)
var vcc = UIViewController()
switch (shortCutType) {
case ShortcutIdentifier.First.type:
vcc = storyboard.instantiateViewController(withIdentifier: "VC1")
handled = true
break
case ShortcutIdentifier.Second.type:
vcc = storyboard.instantiateViewController(withIdentifier: "VC2")
handled = true
break
case ShortcutIdentifier.Third.type:
vcc = storyboard.instantiateViewController(withIdentifier: "VC3")
handled = true
break
case ShortcutIdentifier.Fourth.type:
vcc = storyboard.instantiateViewController(withIdentifier: "VC4")
handled = true
break
default:
break
}
// Display the selected view controller
self.window?.rootViewController?.present(vcc, animated: true, completion: nil)
return handled
}
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: #escaping (Bool) -> Void) {
let handledShortCutItem = handleShortCutItem(shortcutItem)
completionHandler(handledShortCutItem)
}
func applicationDidBecomeActive(_ application: UIApplication) {
guard launchedShortcutItem != nil else { return }
//handleShortCutItem(shortcut)
launchedShortcutItem = nil
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
// If a shortcut was launched, display its information and take the appropriate action
if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem {
launchedShortcutItem = shortcutItem
}
return true
}
How can I present Navigation and Tab bar using 3D Touch
The same way you do it during the normal run of your app. You should not be doing some special thing in response to the user pressing the shortcut item (i.e. your self.window?.rootViewController?.present, which in effect merely puts up a temporary facade); you should be navigating to the actual area of your real app that the shortcut item corresponds to.

keep user logged in ios app swift

I have made app which include login and signup functionality. When I run my app at that time login and other functionality everything is going ok but when I stop my app and run it again login page showing again can I make user logged in when again app launch. Below is my code which I have used in my app.
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(true)
let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
let isLoggedIn:Int = prefs.integerForKey("ISLOGGEDIN") as Int
if (isLoggedIn != 1) {
self.performSegueWithIdentifier("goto_login", sender: self)
} else {
self.usernameLabel.text = prefs.valueForKey("USERNAME") as? String
}
}
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
/*
var rootViewController = self.window!.rootViewController
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main" , bundle: nil)
var isUserLoggedIn:Bool = NSUserDefaults.standardUserDefaults().boolForKey("isUserLoggedIn")
if(!isUserLoggedIn){
var loginViewController = mainStoryboard.instantiateViewControllerWithIdentifier("loginview") as! LoginViewController
window!.rootViewController = loginViewController
window!.makeKeyAndVisible()
}else{
var protectedPage = mainStoryboard.instantiateViewControllerWithIdentifier("profail") as! ProfailViewController
window!.rootViewController = protectedPage
window!.makeKeyAndVisible()
}
*/
return true
}
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
return true
}
}
Within AppDelegate:-
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
let userLoginStatus = UserDefaults.standard.bool(forKey: "isUserLoggedIn")
if(userLoginStatus)
{
let mainStoryBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
.
.
}
Within LoginViewController(Where you have placed business logic for login validation):-
UserDefaults.standard.set(true, forKey: "isUserLoggedIn")
UserDefaults.standard.synchronize()
Within OtherViewController(Where IBAction for Logout is kept):-
UserDefaults.standard.set(false, forKey: "isUserLoggedIn")
UserDefaults.standard.synchronize()
In "didFinishLaunchingWithOptions" method check for user already logged in or not, if yes that set the ProfailViewController to window rootViewController
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let isUserLoggedIn:Bool = NSUserDefaults.standardUserDefaults().boolForKey("isUserLoggedIn")
if(isUserLoggedIn) {
let mainStoryboard = UIStoryboard(name: "Main" , bundle: nil)
let protectedPage = mainStoryboard.instantiateViewControllerWithIdentifier("profail") as! ProfailViewController
window!.rootViewController = protectedPage
window!.makeKeyAndVisible()
}
return true
}

3D Touch shortcuts won't work due to Unexpected Crash

I am trying to add 3D Touch Shortcuts to an application, I have managed to have the shortcuts appear when using 3DTouch on the app icon from the homescreen; however when using the shortcut the application crashes on load and I am unsure why.
I have managed to get the application to load for the bookmarks shortcut but it does not initiate the BookmarksViewController, it just loads the InitialViewController.
The application is embedded within a UITabBarController and a UINavigationController for each Tab. Both View Controllers I am trying to load are in different tabs but the first view in the navigation controller stack.
Does anyone know where I am going wrong ?
info.plist file
App Delegate
enum ShortcutItemType: String {
case Bookmarks
case Favourites
init?(shortcutItem: UIApplicationShortcutItem) {
guard let last = shortcutItem.type.componentsSeparatedByString(".").last else { return nil }
self.init(rawValue: last)
}
var type: String {
return NSBundle.mainBundle().bundleIdentifier! + ".\(self.rawValue)"
}
}
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsShortcutItemKey] as? UIApplicationShortcutItem {
handleShortcutItem(shortcutItem)
}
return true
}
private func handleShortcutItem(shortcutItem: UIApplicationShortcutItem) {
if let rootViewController = window?.rootViewController, let shortcutItemType = ShortcutItemType(shortcutItem: shortcutItem) {
let sb = UIStoryboard(name: "main", bundle: nil)
let favouritesVC = sb.instantiateViewControllerWithIdentifier("FavouritesVC") as! FavouritesTableViewController
let bookmarksVC = sb.instantiateViewControllerWithIdentifier("BookmarksVC") as! BookmarksNotesViewController
switch shortcutItemType {
case .Bookmarks:
rootViewController.presentViewController(bookmarksVC, animated: true, completion: nil)
break
case .Favourites:
rootViewController.presentViewController(favouritesVC, animated: true, completion: nil)
break
}
}
}
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
handleShortcutItem(shortcutItem)
}
}
Storyboard ID
These are the StoryboardID for the View Controllers.
I think you forgot the 's' in com.appName.Bookmark
Or you need to remove the 's' from Bookmarks here:
enum ShortcutItemType: String {
case Bookmarks
case Favourites
Instead, try using a shortcut like this:
if shortcutItem.type == "com.appName.Bookmark"
#available(iOS 9.0, *)
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
if shortcutItem.type == "com.appName.Bookmark" {
}
}

Resources