How to open particular post on the click on push notification - ios

in my app i implemented push notification. when my app is in running state and if push notification come i am handle that with this code.
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print(userInfo)
myid = (userInfo["id"] as? String)!
print(myid)
if let notification = userInfo["aps"] as? NSDictionary,
let alert = notification["alert"] as? String {
var alertCtrl = UIAlertController(title: "Notification", message: alert as String, preferredStyle: UIAlertControllerStyle.Alert)
alertCtrl.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
// Find the presented VC...
var presentedVC = self.window?.rootViewController
while (presentedVC!.presentedViewController != nil) {
presentedVC = presentedVC!.presentedViewController
}
presentedVC!.presentViewController(alertCtrl, animated: true, completion: nil)
}
What i want :: when my app is not running and if push notification come i want to open perticular post based on that notification post id. so how can i do this?
Here is my code
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
SVProgressHUD.setDefaultMaskType(SVProgressHUDMaskType.Black)
UIApplication.sharedApplication().applicationIconBadgeNumber = 0
let dicTemp = launchOptions?["UIApplicationLaunchOptionsRemoteNotificationKey"]
if dicTemp != nil{
window = UIWindow(frame: UIScreen.mainScreen().bounds)
storyboard = UIStoryboard(name: "Main", bundle: nil)
myid = (dicTemp["id"] as? String)!
let controller:pushnotificationpostViewController = self.storyboard.instantiateViewControllerWithIdentifier("pushnotificationpostViewController") as! pushnotificationpostViewController
navigation = UINavigationController(rootViewController: controller)
window?.rootViewController = navigation
window?.makeKeyAndVisible()
}
else
{
window = UIWindow(frame: UIScreen.mainScreen().bounds)
storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller:MainViewController = self.storyboard.instantiateViewControllerWithIdentifier("MainViewController") as! MainViewController
navigation = UINavigationController(rootViewController: controller)
window?.rootViewController = navigation
window?.makeKeyAndVisible()
}
//print(NSUserDefaults.standardUserDefaults().valueForKey("pushnotify")as! Bool)
let notificationTypes: UIUserNotificationType = [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound]
let pushNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
application.registerUserNotificationSettings(pushNotificationSettings)
if (NSUserDefaults.standardUserDefaults().valueForKey("pushnotify")) != nil
{
pushnotification = NSUserDefaults.standardUserDefaults().valueForKey("pushnotify") as! Bool
// let notificationcheck = NSUserDefaults.standardUserDefaults().valueForKey("pushnotify") as! Bool
if (pushnotification == true)
{
application.registerForRemoteNotifications()
}
else
{
application.unregisterForRemoteNotifications()
}
}
else
{
application.registerForRemoteNotifications()
}
return true
}
but by this code i am not getting id means myid is getting nil. so how can i do this?

i think when you quit your application the
didReceiveRemoteNotification method not gets called when you tap on
the notification, instead the method didFinishLaunchingWithOptions
gets called there you have to check weather application is launched by
notification
Put below code in your didFinishLaunchingWithOptions :
var notification: UILocalNotification = (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] as! UILocalNotification)
if notification != nil {
// handle your notification
}
above code is for handling the push notifications if your using local notification then try:
// if launched by the local notification
var notification: UILocalNotification = (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey] as! UILocalNotification)
if notification != nil {
}

Related

How to send the user to a particular view controller upon tapping the notification? [duplicate]

I looked on SO but I wasn't able to find any question that discusses when you receive a push notification how can you then open a specific view controller.
For example if you are creating an app like WhatsApp and you receive two different push notifications ie messages from two different users how would you direct from the app delegate to the respective viewController?
As far as I know in the userinfo dictionary that the appDelegate gives you you can give an ID to a specific viewController but I don't know how to give any a tribute to a specific view controller so that then you could again direct to that viewController.
Kindly include a code snippet with your answer
**** Swift or Objective-C answers are both acceptable ****
You can detect if the app opened from the notification with this code in app delegate. You will need to set the initial view controller when the application state is UIApplicationStateInactive before the app has become active. You can perform any logic there to decide which view controller should be opened and what content should be shown in that view controller.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
if(application.applicationState == UIApplicationStateActive) {
//app is currently active, can update badges count here
} else if(application.applicationState == UIApplicationStateBackground){
//app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
} else if(application.applicationState == UIApplicationStateInactive){
//app is transitioning from background to foreground (user taps notification), do what you need when user taps here
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *viewController = // determine the initial view controller here and instantiate it with [storyboard instantiateViewControllerWithIdentifier:<storyboard id>];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
}
}
Here is the Swift 3 Version with switch/case instead of if/else
open func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
switch application.applicationState {
case .active:
print("do stuff in case App is active")
case .background:
print("do stuff in case App is in background")
case .inactive:
print("do stuff in case App is inactive")
}
}
//This method is called when user tap on the notification
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
print("user clicked on the notification")
let userInfo = response.notification.request.content.userInfo
print(userInfo)
//check your response and navigate to specific view controller
moveToNextViewController()
}
func moveToNextViewController() {
//Add code for present or push view controller
let vc = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier:"ViewController") as! ViewController
self.navigationController?.pushViewController(vc, animated: true)
}
This method is called when user tap on the notification. implement in appdelegate
var navigationC: UINavigationController?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if USERDEFAULT.value(forKey: "isLogin") != nil {
let tabbarvc = MainStoryboard.instantiateViewController(withIdentifier: "TabBarVC") as! TabBarVC
self.navigationC = UINavigationController(rootViewController: tabbarvc)
}else {
let loginvc = MainStoryboard.instantiateViewController(withIdentifier: "LoginVC") as! LoginVC
self.navigationC = UINavigationController(rootViewController: loginvc)
}
self.navigationC?.setNavigationBarHidden(true, animated: false)
self.window?.clipsToBounds = true
self.window?.rootViewController = navigationC
self.window?.makeKeyAndVisible()
return true
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
print("-------------\nUser info in notification -> \(userInfo)\n-------------")
let dict = userInfo["aps"] as? NSDictionary ?? [:]
if USERDEFAULT.value(forKey:"isLogin") != nil{
let type = dict["type"] as? Int ?? 0
switch type {
case 0:
break
case 1:
for vc in self.navigationC!.viewControllers {
if vc is TabBarVc {
let exam = dict["exam"] as? String ?? ""
if exam == ""{
let TestVC = MainStoryboard.instantiateViewController(withIdentifier: "TestVC") as! TestVC
TestVC.chapterId = dict["chapter_id"] as? String ?? ""
TestVC.strSubTitle = dict["chapter"] as? String ?? ""
self.navigationC?.isNavigationBarHidden = true
self.navigationC?.pushViewController(TestVC, animated: true)
}else if exam != ""{
let ExamTestVC = MainStoryboard.instantiateViewController(withIdentifier: "ExamTestVC") as! ExamTestVC
ExamTestVC.examId = dict["exam_id"] as? String ?? ""
ExamTestVC.strSubTitle = dict["exam"] as? String ?? ""
self.navigationC?.isNavigationBarHidden = true
self.navigationC?.pushViewController(ExamTestVC, animated: true)
}
return;
}
}
break
case 2:
for vc in self.navigationC!.viewControllers {
if vc is TabBarVc {
let VideoListVC = MainStoryboard.instantiateViewController(withIdentifier: "VideoListVC") as! VideoListVC
VideoListVC.chapterId = dict["chapter_id"] as? String ?? ""
VideoListVC.video_id = dict["video_id"] as? String ?? ""
VideoListVC.strSubTitle = dict["chapter"] as? String ?? ""
VideoListVC.questionsCount = dict["question_count"] as? Int ?? 0
VideoListVC.testCount = dict["test_count"] as? Int ?? 0
self.navigationC?.isNavigationBarHidden = true
self.navigationC?.pushViewController(VideoListVC, animated: true)
return;
}
}
break
case 3:
break
default: break
}
}else{
let loginVC = SignupiPadStoryboard.instantiateViewController(withIdentifier: "LoginVC") as! LoginVC
SignupStoryboard = SignupiPadStoryboard
self.navigationC = UINavigationController(rootViewController: loginVC)
}
}
OR you can direct open view controller like whatsapp chat..etc.
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void)
{
let userInfo = notification.request.content.userInfo
let dictAps = userInfo["aps"] as! NSDictionary
print(dictAps)
let notification_type = dictAps["notification_type"] as? Int ?? 0
if notification_type == 6{
if isChatActive == false{
completionHandler([.alert, .badge, .sound])
}else{
if USERDEFAULT.value(forKey:"isLogin") != nil{
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ReloadChatMessages"), object: nil, userInfo: (dictAps as! [AnyHashable : Any]))
}else{
completionHandler([.alert, .badge, .sound])
}
}
}else{
completionHandler([.alert, .badge, .sound])
}
}

Swift - How to open specific view controller when push notification received?

I got stuck specific view controller is not move when I tap on push notification alert when application is not open stage totally.
Here is my code:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
/*
fetch and add push notification data
*/
goAnotherVC()
}
func goAnotherVC() {
if (application.applicationState == UIApplicationState.active) {
/* active stage is working */
} else if (application.applicationState == UIApplicationState.inactive || application.applicationState == UIApplicationState.background) {
if (type == "1" || type == "2") {
let storyboard: UIStoryboard = UIStoryboard(name: "MyAppointments", bundle: nil)
let apptVC = storyboard.instantiateViewController(withIdentifier: "NotificationDetailViewController") as! NotificationDetailViewController
let navigationController = UINavigationController.init(rootViewController: apptVC)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
} else if (type == "3") {
let storyboard: UIStoryboard = UIStoryboard(name: "MyAppointments", bundle: nil)
let apptVC = storyboard.instantiateViewController(withIdentifier: "NotificationDetailViewController") as! NotificationDetailViewController
let navigationController = UINavigationController.init(rootViewController: apptVC)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
} else if (type == "4") {
let storyboard: UIStoryboard = UIStoryboard(name: "Enquiry", bundle: nil)
let enqVC = storyboard.instantiateViewController(withIdentifier: "EnquiryDetailViewController") as! EnquiryDetailViewController
let navigationController = UINavigationController.init(rootViewController: enqVC)
self.window?.rootViewController = navigationController
self.window?.makeKeyAndVisible()
}
}
}
I can get notification and tap to move specific VC when application is active. Please help me what I am missing.
Swift 5
Simply, implement the following function which will be called when the user clicked on the notification.
In AppDelegate:
// This method is called when user clicked on the notification
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void)
{
// Do whatever you want when the user tapped on a notification
// If you are waiting for specific data from the notification
// (e.g., key: "target" and associated with "value"),
// you can capture it as follows then do the navigation:
// You may print `userInfo` dictionary, to see all data received with the notification.
let userInfo = response.notification.request.content.userInfo
if let targetValue = userInfo["target"] as? String, targetValue == "value"
{
coordinateToSomeVC()
}
completionHandler()
}
private func coordinateToSomeVC()
{
guard let window = UIApplication.shared.keyWindow else { return }
let storyboard = UIStoryboard(name: "YourStoryboard", bundle: nil)
let yourVC = storyboard.instantiateViewController(identifier: "yourVCIdentifier")
let navController = UINavigationController(rootViewController: yourVC)
navController.modalPresentationStyle = .fullScreen
// you can assign your vc directly or push it in navigation stack as follows:
window.rootViewController = navController
window.makeKeyAndVisible()
}
Note:
If you navigate to a specific controller based on the notification, you should care about how you will navigate back from this controller because there are no controllers in your stack right now. You must instantiate the controller you will back to. In my case, when the user clicked back, I instantiate the home controller and make it the app root again as the app will normally start.
When you app is in closed state you should check for launch option in
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { }
and call your API.
Example:
if let option = launchOptions {
let info = option[UIApplicationLaunchOptionsKey.remoteNotification]
if (info != nil) {
goAnotherVC()
}
}
Swift 5, iOS 13 -
Since iOS 13 "window" is available in SceneDelegate. But the didReceiveNotification method is still present in AppDelegate.
So you have to first access the window from SceneDelegate
let window = (UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.window
Now You can set the rootViewController property of the window
window.rootViewController = viewControllerObject
window.makeKeyAndVisible()

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

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 :) ;)

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

Show uiviewcontroller from remote notification when app is quitted

I'm trying to show a specific viewcontroller when I receive a remote push notification. I've added all of my code into the method didReceiveRemoteNotification:
func application(application: UIApplication, didReceiveRemoteNotification userinfo: [NSObject: AnyObject])
I've added following code:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
let code = (userInfo["aps"] as! [String: AnyObject])
// Call to retrieve blog
if let blog = code["b"] as? NSNumber {
let blogId = blog as! Int
// Show blog from notification
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main",bundle: nil)
var controller = mainStoryboard.instantiateViewControllerWithIdentifier("blogCtrl") as! BlogController
controller.blogId = blogId
var rootController = mainStoryboard.instantiateViewControllerWithIdentifier("navCtrl1") as! UINavigationController
self.window?.rootViewController = rootController
rootController.pushViewController(controller, animated: true)
self.window?.makeKeyAndVisible()
}
if let tonic = code["t"] as? NSNumber {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main",bundle: nil)
var controller = mainStoryboard.instantiateViewControllerWithIdentifier("tonicDetail") as! TonicDetailController
controller.tonicId = tonic as! Int
var rootController = mainStoryboard.instantiateViewControllerWithIdentifier("navCtrl1") as! UINavigationController
self.window?.rootViewController = rootController
rootController.pushViewController(controller, animated: true)
self.window?.makeKeyAndVisible()
}
if let gin = code["g"] as? NSNumber {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main",bundle: nil)
var controller = mainStoryboard.instantiateViewControllerWithIdentifier("GinDetail") as! GinDetailController
controller.ginId = gin as! Int
var rootController = mainStoryboard.instantiateViewControllerWithIdentifier("navCtrl1") as! UINavigationController
self.window?.rootViewController = rootController
rootController.pushViewController(controller, animated: true)
self.window?.makeKeyAndVisible()
}
}
When the app is in background everything works but when the app is quited, and I receive a remote notification it only starts up the application.
Is there a method which can be called if the application was quited before?
When your app launches after quitting the app, in the meanwhile you got remote notification, then didFinishLaunchingWithOptions is first method in AppDelegate which fires on launching the app, check whether you have received any notification or not and perform your operation accordingly.
You must look for this method in app delegate:-
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Now check whether your app has received any push notification or not
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (notification) {
NSLog(#"app received a notification %#",notification);
[self application:application didReceiveRemoteNotification:(NSDictionary*)notification];
}else{
NSLog(#"app did not receive a notification");
}

Resources