Swift receiving push notifications (Parse) when the app is not running - ios

I am building an iOS app using Swift and I want to receive push notifications (Parse) when someone has mentioned me.
I have used a navigation controller as the initial view controller and first view controller is the sign in view controller. In this view controller there is an if statement which checks whether the user in already logged in or not. If the user is already logged in then the app jumps automatically to the main screen.
If the sign in is successful, the app jumps to main screen.
My notifications work fine in the following cases:
The app is running
The app is running on the background, and when I tap on the notification bar, the app jumps on the notification screen
My notifications do not work in the following cases:
The app is running on the background, when I tap the icon with the badge (i.e. 1) it shows the main screen and not the notification screen
The app is not running at all, and I am running it through the notification. In this case the app is stacked on the sign in screen and it is not responding. I think that the problem is because it waits for the user to be signed in.
I do not know whether there is an issue in the AppDelegate.swift file. I have followed the Parse documentation as well as the Starter project for Parse in order to code it.
Following are the methods from the AppDelegate.swift
Method application: didFinishLaunchingWithOptions
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if let notificationPayload = launchOptions? [UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {
let meetingId = notificationPayload["meetingId"] as? String
let targetMeeting = PFObject(withoutDataWithClassName: "Meeting", objectId: meetingId)
targetMeeting.fetchIfNeededInBackgroundWithBlock({ (object, error) -> Void in
if error == nil {
let meetingToRespond = Meeting(id: targetMeeting.objectId!, name: targetMeeting["name"] as! String, location: CLLocationCoordinate2DMake((targetMeeting["location"]?.latitude)!, (targetMeeting["location"]?.longitude)!), day: targetMeeting["dayTime"] as! NSDate)
var rootViewController = self.window?.rootViewController as! UINavigationController
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let notificationScreen = mainStoryboard.instantiateViewControllerWithIdentifier("screenForNotification") as! MeetingToRespondViewController
notificationScreen.meeting = meetingToRespond
rootViewController.pushViewController(notificationScreen, animated: true)
}
})
}
// Enable storing and querying data from Local Datastore.
// Remove this line if you don't want to use Local Datastore features or want to use cachePolicy.
Parse.enableLocalDatastore()
Parse.setApplicationId("###",
clientKey: "###")
PFFacebookUtils.initializeFacebookWithApplicationLaunchOptions(launchOptions)
PFUser.enableAutomaticUser()
let defaultACL = PFACL();
// If you would like all objects to be private by default, remove this line.
defaultACL.setPublicReadAccess(true)
PFACL.setDefaultACL(defaultACL, withAccessForCurrentUser:true)
if application.applicationState != UIApplicationState.Background {
// Track an app open here if we launch with a push, unless
// "content_available" was used to trigger a background push (introduced in iOS 7).
// In that case, we skip tracking here to avoid double counting the app-open.
let oldPushHandlerOnly = !self.respondsToSelector(Selector("application:didReceiveRemoteNotification:fetchCompletionHandler:"))
let noPushPayload: AnyObject? = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey]
if oldPushHandlerOnly || noPushPayload != nil {
PFAnalytics.trackAppOpenedWithLaunchOptions(launchOptions)
}
}
if application.respondsToSelector("registerUserNotificationSettings:") {
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
} else {
let types: UIRemoteNotificationType = [UIRemoteNotificationType.Badge, UIRemoteNotificationType.Alert, UIRemoteNotificationType.Sound]
application.registerForRemoteNotificationTypes(types)
}
return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}
Method application: didRegisterForRemoteNotificationsWithDeviceToken
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let installation = PFInstallation.currentInstallation()
installation.setDeviceTokenFromData(deviceToken)
installation.saveInBackground()
}
Method application: didReceiveRemoteNotification
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
if application.applicationState == .Inactive {
// The application was just brought from the background to the foreground, so we consider the app as having been "opened by a push notification."
PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo)
}
}
Method application:didReceiveRemoteNotification:fetchCompletionHandler
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
if application.applicationState == .Inactive {
PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo)
}
if let meetingId: String = userInfo["meetingId"] as? String {
let targetMeeting = PFObject(withoutDataWithClassName: "Meeting", objectId: meetingId)
targetMeeting.fetchIfNeededInBackgroundWithBlock({ (object, error) -> Void in
// Show meeting to respond view controller
if error != nil {
completionHandler(UIBackgroundFetchResult.Failed)
} else if PFUser.currentUser() != nil {
// Get the meeting
let meetingToRespond = Meeting(id: targetMeeting.objectId!, name: targetMeeting["name"] as! String, location: CLLocationCoordinate2DMake((targetMeeting["location"]?.latitude)!, (targetMeeting["location"]?.longitude)!), day: targetMeeting["dayTime"] as! NSDate)
var rootViewController = self.window?.rootViewController as! UINavigationController
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let notificationScreen = mainStoryboard.instantiateViewControllerWithIdentifier("screenForNotification") as! MeetingToRespondViewController
notificationScreen.meeting = meetingToRespond
rootViewController.pushViewController(notificationScreen, animated: true)
completionHandler(UIBackgroundFetchResult.NewData)
} else {
completionHandler(UIBackgroundFetchResult.NoData)
}
})
}
completionHandler(UIBackgroundFetchResult.NoData)
}
Method applicationDidBecomeActive: application
func applicationDidBecomeActive(application: UIApplication) {
// Clear the badge
let currentInstallation = PFInstallation.currentInstallation()
if currentInstallation.badge != 0 {
currentInstallation.badge = 0
currentInstallation.saveEventually()
}
FBSDKAppEvents.activateApp()
}
Thank you in advance!!! :D :) ;)

Related

App crashes after push notification is tapped when app is killed

I am attempting to launch a specific viewController in my CustomTabBarController after receiving remote notifications. But somehow, the app always crashes when the app is killed.
Meaning to say, kill the app -> received push notifications -> tap the notifications -> app launches and crashed. This also happens when I tap the notification from the lockscreen.
I am able to execute when the app is in the background, but not when the app is killed. My code so far:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
...
if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? NSDictionary {
guard let rootViewController = self.window?.rootViewController as? CustomTabBarController else {
return true
}
rootViewController.selectedIndex = 1
}
return true
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
if application.applicationState == .background || application.applicationState == .inactive {
guard let rootViewController = self.window?.rootViewController as? CustomTabBarController else {
return
}
rootViewController.selectedIndex = 1
}
}
I've followed this post to check the launchOptions, but it still crash. What can I try next?
Comment these 2 lines
// window = UIWindow(frame: UIScreen.main.bounds)
// window?.makeKeyAndVisible()
as overriding the window property destroys the initialization from storyboard (makes rootVC nil) and before return true window must have one

IOS app won't display push notification when in background. Swift

Ok so my push notification work like a charm when the app is running in the foreground. But when ever I enter into the background, the app never receives the push notification. Its like the notification falls on deaf ears.
So this is what happening. When the app is first started, I can received notification. When I close and reopen the app I can receive notification. But when the app is closed in the background I cannot receive notification. I print off when the app goes into the background and when the app becomes active so I know that its not closing I think. Because its printing that its going into the background, so it should be running.
So this is what I have for the app deligate class:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//OTHER THINGS
//Open the Push note page
if launchOptions != nil
{
print(launchOptions)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier(myPage)
self.window?.rootViewController = vc
}
//handel push note if app is closed
//Sends it to the regular handler for push notifcaiton
//didrecivepushnotificaiton
if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary
{
print("Got A Push Note when I was closed")
self.application(application, didReceiveRemoteNotification: remoteNotification as [NSObject : AnyObject])
}
}
func application( application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken
deviceToken: NSData ) {
print("DEVICE TOKEN = \(deviceToken)")
//convert the device token into a string
let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
var token = ""
for i in 0..<deviceToken.length {
token += String(format: "%02.2hhx", arguments: [tokenChars[i]])
}
print("token: " + token)
//store the user device token for apns push notification
loginInformation.setObject(token, forKey: "token")
self.loginInformation.synchronize()
}
// [START ack_message_reception]
func application( application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print("Recived Push Notificaion")
var myMess :String = ""
var url : String = ""
var myTitle : String = ""
if var alertDict = userInfo["aps"] as? Dictionary<String, String> {
print("Alert Dict")
print(alertDict)
url = alertDict["url"]!
myMess = alertDict["alert"]!
myTitle = alertDict["mytitle"]!
//store the url for the push control view
loginInformation.setObject(url, forKey: "URL")
loginInformation.setObject(myMess, forKey: "Message")
loginInformation.setObject(myTitle, forKey: "Title")
self.loginInformation.synchronize()
}else{print("No go")}
application.applicationIconBadgeNumber = 0
//post notification.
NSNotificationCenter.defaultCenter().postNotificationName("PushReceived", object: nil, userInfo: userInfo)
if myTitle == ""
{
myTitle = “New Title“
}
if myMess == ""
{
myMess = “All Hail Gus“
}
let alert = UIAlertController(title: myTitle, message: myMess, preferredStyle: UIAlertControllerStyle.Alert)
//Close Button
alert.addAction(UIAlertAction(title: "次回", style: UIAlertActionStyle.Default, handler: nil))
self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)
}
func registrationHandler(registrationToken: String!, error: NSError!) {
}
// [START receive_apns_token_error]
func application( application: UIApplication, didFailToRegisterForRemoteNotificationsWithError
error: NSError ) {
print(error)
}
I think I have all the right setting on this too. But I am not too sure now. The push notifications did work but I made a lot of changes and haven't tested them in a while.
And this is an example of the payload
{"aps":{"alert":"Gus Message.","badge":"1", "url":"https://www.gus.com","mytitle":"Gus Title"}}
To fully implement APNS servie, u have to handle three cases:
inactive
foreground
background
the inactive mode should be handled in didFinishLaunchingWithOptions method
//receive apns when app in inactive mode, remaining message hint display task could be sum up by the code in applicationwillenterforeground
if let options = launchOptions {
if options[UIApplicationLaunchOptionsRemoteNotificationKey] != nil {
let userInfo: NSDictionary = options[UIApplicationLaunchOptionsRemoteNotificationKey] as! NSDictionary
let apsInfo: NSDictionary = userInfo["aps"] as! NSDictionary
//parse notification body message ...
NSNotificationCenter.defaultCenter().postNotificationName(APP_NOTIF_RECEIVE_REMOTE_NOTIF, object: userInfo)
APService.handleRemoteNotification(userInfo as! [NSObject : AnyObject])
//Update badge number
let badgeIndex = apsInfo["badge"] as! Int
UIApplication.sharedApplication().applicationIconBadgeNumber = badgeIndex
}
}
} else if options[UIApplicationLaunchOptionsURLKey] != nil {
if let url = launchOptions?[UIApplicationLaunchOptionsURLKey] as? NSURL {
print(url)
}
}
}
the remaining two cases should be handle in didReceiveRemoteNotification method
//receive apns when app in background mode
let apsInfo: NSDictionary = userInfo["aps"] as! NSDictionary
if UIApplication.sharedApplication().applicationState != UIApplicationState.Active{
//TODO: temporary method, need further update
//judge notification type
if let _ = userInfo["inviterName"] as? String {
//notification for group invite
}else{
//Update badge number
if let badgeInt = apsInfo["badge"] as? Int {
UIApplication.sharedApplication().applicationIconBadgeNumber = badgeInt > 0 ? badgeInt: 1
}else{
UIApplication.sharedApplication().applicationIconBadgeNumber = 1
}
//turn on trigger to enable message hint btn on recorder vc when it appear
NSUserDefaults.standardUserDefaults().setBool(true, forKey: REMOTE_NOTIF_REMAINING)
}
}
//receive apns when app in forground mode
else{
//TODO: temporary method, need further update
//judge notification type
if let _ = userInfo["inviterName"] as? String {
//notification for group invite
NSNotificationCenter.defaultCenter().postNotificationName(APP_NOTIF_RECEIVE_GROUP_NOTIF, object:nil)
}else{
//notificate recorder vc to display message hint directly
NSNotificationCenter.defaultCenter().postNotificationName(APP_NOTIF_RECEIVE_REMOTE_NOTIF, object: userInfo)
}
}
APService.handleRemoteNotification(userInfo)
completionHandler(UIBackgroundFetchResult.NewData)

Why not able to handle APNS Push notification and Local notification?

I am working with Push notification and local notification also but in foreground notification working fine but when terminate app in this condition i can not able to redirect specific view when tap on notifications.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Check if launched from notification
// 1
if let notification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [String: AnyObject] {
// 2
let aps = notification["aps"] as! [String: AnyObject]
//Redirect to notification view
handlePushMessage(aps)
}else if let notification = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? [String: AnyObject] {
// 2
self.postData = notification["aps"] as! [String: AnyObject]
//Redirect to notification view
didTapNotification()
}else{
//Session
//Redirect to Main view
checkUserSession()
}
return true
}
I am facing this facing this problem from both APNS notification and local notification when app is Inactive or terminate.Please help me fro find the solution.
How about you try in didReceiveRemoteNotification function?
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
if(application.applicationState == UIApplicationStateBackground){
}else if(application.applicationState == UIApplicationStateInactive){
}
}
try this code, you can modify it according to you requirement. if you have any problem understanding this logic let me know. didReceiveRemoteNotification with completionHandler works both in background and in foreground. Don't forget to do appropriate changes in plist to support background fetch and background notification.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
application.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
if let notification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [String: AnyObject] {
notificationDataDict = notification;
}
return true
}
func handleRemoteNotificationWithUserInfo(application:UIApplication, userInfo:NSDictionary){
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
print(userInfo)
if application.applicationState != .Inactive{
notificationDataDict = userInfo;
if let navigationController = self.window?.rootViewController as? UINavigationController{
if application.applicationState == .Active{
if application.backgroundRefreshStatus == .Available{
completionHandler(.NewData)
self.handleRemoteNotificationWithUserInfo(application, userInfo: userInfo)
}
else
{
completionHandler(.NoData)
}
}
else{
completionHandler(.NewData)
self.handleRemoteNotificationWithUserInfo(application, userInfo: userInfo)
}
}
}
}
Finally i got the solution for Manage APNS Push notification and Local notification, its working fine now.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)
//Register here For Notification
if #available(iOS 9, *) {
let notificationTypes: UIUserNotificationType = [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound]
let pushNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()
}else{
UIApplication.sharedApplication().registerUserNotificationSettings(
UIUserNotificationSettings(forTypes: .Alert, categories: nil))
application.registerForRemoteNotifications()
}
dispatch_async(dispatch_get_main_queue()) {
// Check if launched from notification
// 1
if let notification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [String: AnyObject] {
// 2
let aps = notification["aps"] as! [String: AnyObject]
handlePushMessage(aps)
}else if let notification = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification {
// 2
self.postData = notification.userInfo as! [String: AnyObject]
didTapNotification()
}else{
//Session
checkUserSession()
}
}
}

Using 3D Touch in my application

So i am trying to add 3D Touch on my application icon using shortCutItems. Here is my AppDelegate.swift:
import UIKit
import Parse
//MARK: - Handle QuickActions For ShorCut Items -> AppDelegate Extension
#available(iOS 9.0, *)
typealias HandleForShorCutItem = AppDelegate
#available(iOS 9.0, *)
extension HandleForShorCutItem {
/// Define quick actions type
enum QuickActionsType: String {
case JegHarAldri = "JEGHARALDRI"
case Pling = "PLING"
case FlasketutenPekerPå = "FLASKETUTENPEKERPÅ"
case KortetTaler = "KORTETTALER"
}
}
#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")
// Register for Push Notitications
if application.applicationState != UIApplicationState.Background {
// Track an app open here if we launch with a push, unless
// "content_available" was used to trigger a background push (introduced in iOS 7).
// In that case, we skip tracking here to avoid double counting the app-open.
let preBackgroundPush = !application.respondsToSelector("backgroundRefreshStatus")
let oldPushHandlerOnly = !self.respondsToSelector("application:didReceiveRemoteNotification:fetchCompletionHandler:")
var pushPayload = false
if let options = launchOptions {
pushPayload = options[UIApplicationLaunchOptionsRemoteNotificationKey] != nil
}
if (preBackgroundPush || oldPushHandlerOnly || pushPayload) {
PFAnalytics.trackAppOpenedWithLaunchOptions(launchOptions)
}
}
if application.respondsToSelector("registerUserNotificationSettings:") {
if #available(iOS 8.0, *) {
let types:UIUserNotificationType = ([.Alert, .Sound, .Badge])
let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: types, categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
} else {
application.registerForRemoteNotificationTypes([.Alert, .Sound, .Badge])
}
}
else {
// Register for Push Notifications before iOS 8
application.registerForRemoteNotificationTypes([.Alert, .Sound, .Badge])
}
//// - Add lines before the return true
let currentInstallation: PFInstallation = PFInstallation.currentInstallation()
currentInstallation.badge = 0
currentInstallation.saveEventually()
//UIApplication.sharedApplication().applicationIconBadgeNumber = 11
return true
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let installation = PFInstallation.currentInstallation()
installation.setDeviceTokenFromData(deviceToken)
installation.saveInBackground()
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
if error.code == 3010 {
print("Push notifications are not supported in the iOS Simulator.")
} else {
print("application:didFailToRegisterForRemoteNotificationsWithError: %#", error)
}
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
PFPush.handlePush(userInfo)
if application.applicationState == UIApplicationState.Inactive {
PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo)
}
}
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 inactive 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:.
NSUserDefaults.standardUserDefaults().removeObjectForKey("KortetTalerKey")
NSUserDefaults.standardUserDefaults().removeObjectForKey("TerningspilletKey")
NSUserDefaults.standardUserDefaults().removeObjectForKey("segmentKey")
NSLog("Keys Deleted")
}
//MARK: - Handle QuickActions For ShorCut Items -> AppDelegate Extension
typealias HandleForShorCutItem = AppDelegate
func handleShortcut( shortcutItem:UIApplicationShortcutItem ) -> Bool {
// Construct an alert using the details of the shortcut used to open the application.
let alertController = UIAlertController(title: "Shortcut Handled", message: "\"\(shortcutItem.localizedTitle)\"", preferredStyle: .Alert)
let okAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(okAction)
// Display an alert indicating the shortcut selected from the home screen.
window!.rootViewController?.presentViewController(alertController, animated: true, completion: nil)
return true
}
/// Shortcut Item, also called a Home screen dynamic quick action, specifies a user-initiated action for app.
func QuickActionsForItem(shortcutItem: UIApplicationShortcutItem) -> Bool {
// set handled boolean
var isHandled = false
// Get the string type from shorcut item
if let shorchutItemType = QuickActionsType.init(rawValue: shortcutItem.type) {
// Get root navigation controller + root tab bar controller
let rootNavigationController = window!.rootViewController as? UINavigationController
let tabbarController = window!.rootViewController as? UITabBarController
// if needed pop to root view controller
rootNavigationController?.popToRootViewControllerAnimated(false)
// return tabbarcontroller selected
switch shorchutItemType {
case .JegHarAldri:
let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewControlleripad : UIViewController = mainStoryboardIpad.instantiateViewControllerWithIdentifier("JEGHARALDRI") as UIViewController
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window?.rootViewController = initialViewControlleripad
self.window?.makeKeyAndVisible()
isHandled = true
return true
case .Pling:
let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewControlleripad : UIViewController = mainStoryboardIpad.instantiateViewControllerWithIdentifier("PLING") as UIViewController
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window?.rootViewController = initialViewControlleripad
self.window?.makeKeyAndVisible()
isHandled = true
return true
case .FlasketutenPekerPå:
let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewControlleripad : UIViewController = mainStoryboardIpad.instantiateViewControllerWithIdentifier("FLASKETUTENPEKERPÅ") as UIViewController
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window?.rootViewController = initialViewControlleripad
self.window?.makeKeyAndVisible()
isHandled = true
return true
case .KortetTaler:
let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewControlleripad : UIViewController = mainStoryboardIpad.instantiateViewControllerWithIdentifier("KORTETTALER") as UIViewController
self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
self.window?.rootViewController = initialViewControlleripad
self.window?.makeKeyAndVisible()
isHandled = true
return true
}
}
return isHandled
}
/// Calls - user selects a Home screen quick action for app
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
// perform action for shortcut item selected
let handledShortCutItem = QuickActionsForItem(shortcutItem)
completionHandler(handledShortCutItem)
}
}
I have some issues. FYI! I do not have a tabBarController in my project.
When i open my application using the 3D Touch items, it freezes for 4-5 seconds before it opens the application. When the application is opened, the back buttons does not work.
So is there any possible ways to open the app on the initial controller, and perform segue to the correct view controller?
private func showViewController(viewControllerKey: ViewControllerKeys) -> Bool
{
// Init the storyboard
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// Init the root navigationController
guard let navigationController = storyboard.instantiateInitialViewController() as? UINavigationController else { return false }
// Set the root navigationController as rootViewController of the application
UIApplication.sharedApplication().keyWindow?.rootViewController = navigationController
// Init the wanted viewController
guard let viewController = storyboard.instantiateViewControllerWithIdentifier(viewControllerKey.rawValue) else { return false }
// Push this viewController
navigationController.pushViewController(viewController, animated: false)
return true
}
Please find more impletation details of how to handle quick actions in my QuickActionsManager, or checkout the entire 3DTouch sample of code

Perform segue when Push Notification opens App

I'm trying to redirect the user to a ViewController when he touches the Push Notification. This is working fine when the user has the App open in background, but it's not working when it has to open the App.
After some research, I have learned when the App opens due tu a push notification, it only reads the "didFinishLaunchingWithOptions".
So, I assume now I need to make some "if" statement to make the segue when the push notification is set, but I don't know how to detect the push notification because it's my first time using notifications in my app.
Here is my code:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Parse.setApplicationId(MY_APP_ID, clientKey: MY_CLIENT_KEY)
// Registramos la Push Notification
if application.applicationState != UIApplicationState.Background {
let preBackgroundPush = !application.respondsToSelector("backgroundRefreshStatus")
let oldPushHandlerOnly = !self.respondsToSelector("application:didReceiveRemoteNotification:fetchCompletionHandler:")
var pushPayload = false
if let options = launchOptions {
pushPayload = options[UIApplicationLaunchOptionsRemoteNotificationKey] != nil
}
if (preBackgroundPush || oldPushHandlerOnly || pushPayload) {
PFAnalytics.trackAppOpenedWithLaunchOptions(launchOptions)
}
}
if application.respondsToSelector("registerUserNotificationSettings:") {
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
}
else {
//let types = UIRemoteNotificationType.Badge | UIRemoteNotificationType.Alert | UIRemoteNotificationType.Sound
//application.registerForRemoteNotificationTypes(types)
// Access the storyboard and fetch an instance of the view controller
}
// Change navigation bar appearance
UINavigationBar.appearance().barTintColor = UIColor(hex: 0x00B7BB)
UINavigationBar.appearance().tintColor = UIColor.whiteColor()
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName:UIColor.whiteColor()]
if let barFont = UIFont(name: "Avenir Next", size: 20.0) {
UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName:UIColor.whiteColor(), NSFontAttributeName:barFont]
}
UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent
return true
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let installation = PFInstallation.currentInstallation()
installation.setDeviceTokenFromData(deviceToken)
installation.saveInBackground()
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
if error.code == 3010 {
print("Push notifications are not supported in the iOS Simulator.")
} else {
print("application:didFailToRegisterForRemoteNotificationsWithError: %#", error)
}
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
PFPush.handlePush(userInfo)
if application.applicationState == UIApplicationState.Inactive {
PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo)
}
// Access the storyboard and fetch an instance of the view controller
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let viewController = storyboard.instantiateViewControllerWithIdentifier("UltimaMarca")
// Then push that view controller onto the navigation stack
let rootViewController = self.window!.rootViewController as! UINavigationController
rootViewController.pushViewController(viewController, animated: true)
}
Do you know some tutorial, guideline or code to show me? Because I have found some lines of code in Objective-C but they are very old and I cannot use it.
Thanks,

Resources