Fire PushNotifications at Specific times - Swift - ios

Hi I was wondering if there was a way to display a push notification with the user's approval on specific days. I currently have a toggle for Push Notifications, and when this toggle is called, it should display a picker view for when the user would like these notifications to come. For example, the user could choose the notifications to come weekly, daily, monthly(this would be really nice), or yearly. Also, having the user able to choose which days it comes specifically would be a nice touch. I am not sure as to how I could do this. I would appreciate any guidance or help throughout this process.
Background: I am making an app for my high school's newspaper and would like to remind the user to check out the app. Notifying the user on the first of every month would be nice because our school releases a new issue out on the first of every month.
Here are is a screenshot of what my app looks like now.
Here is my current AppDelegate.swift code as well for reference:
//
// AppDelegate.swift
// TheGunnOracleApp
//
// Created by Rajat Khare on 11/22/16.
// Copyright © 2016 RDKhare. All rights reserved.
//
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if(!UserDefaults.standard.bool(forKey: "HasLaunchedOnce"))
{
UserDefaults.standard.set(true, forKey: "HasLaunchedOnce")
UserDefaults.standard.synchronize()
}
else{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
self.window!.rootViewController = storyboard.instantiateViewController(withIdentifier: "StartAfterFirst")
self.window?.makeKeyAndVisible()
}
if Reachability.checkIntenetRechable() == false {
let alert = UIAlertController(title: "No Internet Connection", message: "The Internet connection appears to be offline. Please connect to Wi-Fi or use Cellular Data to continue", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
}
return true
}
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
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:.
}
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: #escaping (Bool) -> Void) {
if shortcutItem.type == "com.rdkhare.Home"{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let frontNavigationController = storyboard.instantiateViewController(withIdentifier: "VCHome")
let rearNavigationController = storyboard.instantiateViewController(withIdentifier: "menuVC")
let mainRevealController : SWRevealViewController = SWRevealViewController(rearViewController: rearNavigationController, frontViewController: frontNavigationController)
self.window?.rootViewController? = mainRevealController
// let homeVC = sb.instantiateViewController(withIdentifier: "homePage1") as! WebViewHome
// let root = UIApplication.shared.keyWindow?.rootViewController
// let navController = UINavigationController(rootViewController: homeVC)
// root?.present(navController, animated: true, completion: {
// completionHandler(true)
// })
}
}
}

Related

Making Offline Mode work across all screens in iOS app

I am trying to setup a clean way of handling when a user goes offline, currently if a user is offline I am pushing a new screen to the top of the stack with a message to connect to the internet. This is working perfectly for the one screen it is setup on, but I want this code to work on any screen the user is on. I am trying to put this into the app delegate and have the code shared across all screens but it is not working. The end goal is if the user is on any screen in my app and loses connection, to show the offline view controller - currently this is only working on the home screen.
Also I do not want to use Alamo / Firebase or any other 3rd party to handle this if possible.
This is the home screen code and everything working as expected:
import UIKit
class ViewController: UIViewController, UIAlertViewDelegate {
let reachability = try! Reachability()
override func viewDidLoad() {
super.viewDidLoad()
// When network is unreachable, present offline view controller
reachability.whenUnreachable = { _ in
let vc = self.storyboard?.instantiateViewController(withIdentifier: "OfflineViewController")
vc?.modalPresentationStyle = .fullScreen
self.present(vc!, animated: true, completion: nil)
}
do {
try reachability.startNotifier()
} catch {
print("Unable to start notifier")
}
}
}
This is the code for the offline view controller - it is also working as expected
import UIKit
class OfflineViewController: UIViewController {
let reachability = try! Reachability()
override func viewDidLoad() {
super.viewDidLoad()
do {
try reachability.startNotifier()
} catch {
print("Unable to start notifier")
}
}
#IBAction func tapTryAgain(_ sender: Any) {
reachability.whenReachable = { reachability in
self.dismiss(animated: true, completion: nil)
}
}
}
Now when I try to put all the code in the app delegate, it does not work -- This the part I need help with - note that I am commenting out the reachability code from home screen when I try this out
import UIKit
#main
class AppDelegate: UIResponder, UIApplicationDelegate {
let reachability = try! Reachability()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Note nothing happens when user goes offline with this code
reachability.whenUnreachable = { _ in
print("Not reachable")
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let offlineVC = storyboard.instantiateViewController(withIdentifier: "OfflineViewController")
offlineVC.modalPresentationStyle = .fullScreen
let appDelegate = UIApplication.shared.delegate
appDelegate?.window??.addSubview(offlineVC.view)
appDelegate?.window??.bringSubviewToFront(offlineVC.view)
}
do {
try reachability.startNotifier()
} catch {
print("Unable to start notifier")
}
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
I suppose the problem is that you are trying to use window from AppDelegate, but it will always be nil, since your are using SceneDelegate. Just move this code to SceneDelegate, everything will work as it should then.

Present ViewController from UNNotificationRequest when user taps on notification

I am currently developing an app in Swift 4 that includes local notifications. I am trying to run a specific piece of code when the user taps on the notification like presenting a specific ViewController. I can't find the answer on stack overflow because most of the functions in App delegate are deprecated.
Here is the code I use for the notifications:
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Consejo"
content.body = "Haga clic en la notificacion para ver el consejo del dia."
content.sound = UNNotificationSound.default()
var dateComponents = DateComponents()
if let hour = pickerdatehour {
if let minute = pickerdateminute{
dateComponents.hour = hour
dateComponents.minute = minute
dateComponents.second = 0
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
center.add(request, withCompletionHandler: nil)
The code I am trying to execute from the app delegate is:
import UIKit
import Firebase
import UserNotifications
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
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) {
}
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 userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
print("tes")
let sb = UIStoryboard(name: "Main", bundle: nil)
let otherVC = sb.instantiateViewController(withIdentifier: "consejos") as! ConsejosViewController
window?.rootViewController = otherVC;
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
print("tes")
let sb = UIStoryboard(name: "Main", bundle: nil)
let otherVC = sb.instantiateViewController(withIdentifier: "consejos") as! ConsejosViewController
window?.rootViewController = otherVC;
}
}
What am I doing wrong? The code on app delegate is never even executed.
Any help is appreciated
You need to set UNUserNotificationCenter delegate to self to call UNUserNotificationCenter's delegate methods like below:
let center = UNUserNotificationCenter.current()
center.delegate = self

EXC_BAD_ACCESS runtime error when setting a static property in xcode

Working on an IoT program, but still getting my foot in the door, what the program is supposed to do now is just show a message when the user successfully authenticates using the Touch ID. And it should do that every time the user opens the program whether it is launching for the first time or it is becoming active after being in background.
Program runs, but when it reaches the block where it tried to set a static boolean property that tracks the authentication state it gives me this error:
Here is the full code:
AppDelegate.swift:
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
print("Launching...")
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.
print("Exiting...")
}
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.
ViewController.userIsAuthenticated = false
print("Exited")
}
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.
print("Opening...")
}
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("Opened")
let viewInstance = ViewController()
viewInstance.authenticateUser()
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
print("Terminating!")
}
}
ViewController.swift:
import UIKit
import LocalAuthentication
#IBDesignable class ViewController: UIViewController {
//MARK: Properties
static var userIsAuthenticated: Bool{
get{
return false
}
set{
userIsAuthenticated = newValue
let alert = UIAlertController(title: "", message: "Authentication Successful!", preferredStyle: .actionSheet)
let viewInstance = ViewController()
viewInstance.present(alert, animated: true)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = UIColor.init(red: 0.3, green: 0.48, blue: 0.78, alpha: 1.0)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func authenticateUser(){
if ViewController.userIsAuthenticated != true {
let authenticateUser = LAContext()
var authenticationError: NSError? = nil
let authenticationReason = "Authentication is needed to access your house!"
if authenticateUser.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &authenticationError){
authenticateUser.evaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, localizedReason: authenticationReason, reply: {(success, error) in
if(success){
ViewController.userIsAuthenticated = true
}else{
print(error!.localizedDescription)
}
})
}else{
print("Authentication Error!", authenticationError!)
}
}
}
func displayAnAlert(title:String?, message: String?) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
print("Cancel")
})
alert.addAction(UIAlertAction(title: "OK", style: .default) { _ in
print("OK")
})
self.present(alert, animated: true)
}
}
EDIT
NOW the error is gone but the alert doesn't show up and it gives me this error:
Here is the new code:
AppDelegate.swift:
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
print("Launching...")
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.
print("Exiting...")
}
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.
ViewController.userIsAuthenticated = false
print("Exited")
}
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.
print("Opening...")
}
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("Opened")
let viewInstance = ViewController()
viewInstance.authenticateUser()
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
print("Terminating!")
}
}
ViewController.swift:
import UIKit
import LocalAuthentication
#IBDesignable class ViewController: UIViewController {
//MARK: Properties
static var userIsAuthenticated: Bool!{
didSet{
let alert = UIAlertController(title: "", message: "Authentication Successful!", preferredStyle: .actionSheet)
let viewInstance = ViewController()
viewInstance.present(alert, animated: true)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = UIColor.init(red: 0.3, green: 0.48, blue: 0.78, alpha: 1.0)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func authenticateUser(){
if ViewController.userIsAuthenticated != true {
let authenticateUser = LAContext()
var authenticationError: NSError? = nil
let authenticationReason = "Authentication is needed to access your house!"
if authenticateUser.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &authenticationError){
authenticateUser.evaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, localizedReason: authenticationReason, reply: {(success, error) in
if(success){
ViewController.userIsAuthenticated = true
}else{
print(error!.localizedDescription)
}
})
}else{
print("Authentication Error!", authenticationError!)
}
}
}
func displayAnAlert(title:String?, message: String?) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in
print("Cancel")
})
alert.addAction(UIAlertAction(title: "OK", style: .default) { _ in
print("OK")
})
self.present(alert, animated: true)
}
}
Since my comment on your question you have edited the question with a new error stating that you are attempting to present your alert on a view which is not in the window heirarchy. This is because you have just created a brand new view:
let viewInstance = ViewController()
which is not associated with any window... hence the error.
Presumably you did't want a new view at all, but probably the view you already have that is performing authenticateUser(). If userIsAuthenticated was an instance property that view would simply be available as self, but your property is static and so this is not the case.
There is no simple answer to your problem without redesigning your solution for you, and that is something you need to do! Time to take a step back and think. Ask yourself why your property is static, why you are trying to issue alerts from a property setter, etc.
HTH

User Notifications Swift 3

I want to send simple User Notifications when a Button is pressed. I used a tutorial from the internet, bit it still doesn't work.
The error is "Thread 1: Signal SIGABRT" in the AppDelegate
Here ist the Code:
import UIKit
import UserNotifications
class Map: UIViewController, UNUserNotificationCenterDelegate {
override func viewDidLoad() {
super.viewDidLoad()
//Senden von Mitteilungen?
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
}
// Do any additional setup after loading the view.
}
#IBAction func Notification(_ sender: Any) {
//Set the content of the notification
let content = UNMutableNotificationContent()
content.title = "Achtung!"
content.subtitle = "Verbindung zum Beacon wurde getrennt"
content.body = "---"
//Set the trigger of the notification -- here a timer.
let trigger = UNTimeIntervalNotificationTrigger(
timeInterval: 10.0,
repeats: false)
//Set the request for the notification from the above
let request = UNNotificationRequest(
identifier: "10.second.message",
content: content,
trigger: trigger
)
//Add the notification to the currnet notification center
UNUserNotificationCenter.current().add(
request, withCompletionHandler: nil)
}
}
This is the App Delegate:
import UIKit
import Firebase
import CoreLocation
import UserNotifications
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FIRApp.configure()
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:.
}
}
//EXTENSIONS
// Die Tastatur wird geschlossen, sobald der User außerhalb von ihr klickt
extension UIViewController {
func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
}
func dismissKeyboard() {
view.endEditing(true)
}
}
I hope someone knows my mistake :)
Rename your #IBAction method to something else. You have a namespace conflict.
Ensure the #IBAction is actually linked to a button and fired (add a comment or breakpoint to the method).
Edit: Move your FIRApp.configure() out of applicationDidFinishLaunchingWithOptions. This has been known to cause crashes.
...
override init() {
FIRApp.configure()
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
return true
}
...
Tip: start method names with a lowercase letter. Classes with uppercase letters. This way you can easily identify these later.

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