0

Hy I am new to iOS but somehow I manged to complete some tasks. I am working on app that sets reminders for user. So for this I am using Local notifications (UNUserNotificationCenterDelegate).

Everything is working good and fine. I have written some code, I am receiving notification at scheduled time and I have handled following cases.

  • When app is in background
  • When app is in forground.

My app handles these both cases perfectly or you can say as I needed. but I am helpless in following case

when the App is removed from recent, or not even running in background at all,and a that time if the scheduled notification pops up, and user taps the notification, It opens the splash view controller then opens my app main view controller, where as I need to go to same view controller from where user set the scheduled time for reminder.

I think I am quite clear in what I want and what is happening. Is there any changes to do that. I know it can be possible as Whats App and other apps are also doing this. Please help me in doing this. ...

Note: I am using UserNotifications (Local notification) and Deployment target is 10.3

Update: I saw this link has same need as mine but I do not know what the selected answer suggest as I am new to iOS so I am not sure what and how to do:

A.s.ALI
  • 1,992
  • 3
  • 22
  • 54

2 Answers2

1

When your app launches via LocalNotification your UNUserNotificationCenterDelegate method userNotificationCenter didReceive response will be called.

So I would recommend you to present your notification on top of current view controller as like below approach.

//Add this extension in any of your class
extension UIApplication {

@objc class func topViewController(_ base: UIViewController?) -> UIViewController? {

    var baseController = base

    if baseController == nil{

        baseController = UIApplication.shared.keyWindow?.rootViewController
    }

    if let nav = baseController as? UINavigationController {
        return topViewController(nav.visibleViewController)
    }

    if let tab = baseController as? UITabBarController {
        if let selected = tab.selectedViewController {
            return topViewController(selected)
        }
    }

    return baseController
}

}

//In your `userNotificationCenter didReceive response` method
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {


    if response.actionIdentifier == "YourIdentifier"{

        let controllerToPresent = MyNotificationViewController(nibName: "MyNotificationViewController", bundle: nil)
        controllerToPresent.notificationInfo = response.notification.request.content.userInfo

        //If navigation flow needed, add controllerToPresent to nav controller
        let navConroller = UINavigationController(rootViewController: controllerToPresent)
        UIApplication.topViewController(nil)?.present(navConroller, animated: true, completion: nil)

        //If navigation flow not needed, present directly
        UIApplication.topViewController(nil)?.present(controllerToPresent, animated: true, completion: nil)
    }

    completionHandler()
}
Natarajan
  • 3,241
  • 3
  • 17
  • 34
  • I did not understand this answer/// – A.s.ALI Dec 04 '18 at 07:06
  • this method is in my view controller that I wish to open func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { – A.s.ALI Dec 04 '18 at 07:15
  • kindly tell me how to do it – A.s.ALI Dec 04 '18 at 07:15
  • Is your delegate methods written in your very first view controller(used during app launch)? – Natarajan Dec 04 '18 at 07:32
  • I do not know what you saying., but let me tell you the reminder View controller is the place where user schedule his reminder. This view controller is the main thing to make and register reminder, it recives notifications, it register notifications. Also it ask for permission from user for notifications. I have seen many code where permision was asked in app delegate, and also the Notification delegated method were also written int the app delegate, but in my case I have written these all in my view controller – A.s.ALI Dec 04 '18 at 07:40
  • I just asked a simple question, you said : "in my case I have written these all in my view controller", is this controller your first View controller when app is opened? – Natarajan Dec 04 '18 at 07:49
  • no it is my 3rd view controller and I am using Tabbar – A.s.ALI Dec 04 '18 at 07:53
  • ok, then you may have to move your Delegate methods and permission request code to AppDelegate as I mentioned in this post https://stackoverflow.com/a/53557313/3420996. – Natarajan Dec 04 '18 at 07:56
  • this question was asked by me , and I implemented this solution but in view controller – A.s.ALI Dec 04 '18 at 08:02
  • yeah, I know. I recommend you to use AppDelegate instead of view controller. So that you can present your view controller once app opened/re-launched via Local notification. – Natarajan Dec 04 '18 at 08:07
  • Please read this article to know more about iOS app lifecycle https://developer.apple.com/library/archive/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html – Natarajan Dec 04 '18 at 08:08
1

So, your problem is when the app is killed or inactive and then when user tap the notification the reminder screen will show up, right?

Here's the case: Notification shows (inactive/killed) -> tap notification -> splash -> reminder screen.

You should save your data that you want to show in notification. iOS will save any notification data in remoteNotification.

So, when user opens the app from inactive, the first thing that will be called is launchOption in AppDelegate.

Here's the example:

    if launchOptions != nil {
    // get data from notificaioton when app is killed or incative
           if let userInfo = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? NSDictionary  {
                   // Do what you want, you can set set the trigger to move it the screen as you want, for your case is to reminder screen
                }
            }