Search code examples
iosswiftuitableviewuilocalnotification

Selecting tableview cell from local notification when app closed


I am implementing local notifications in my iOS10 app. It is a simple master-detail app where users enter items (medicinal drugs) with expiry dates. Notifications are triggered when an item expires.

The app structure is a DrugTableViewController and a DetailViewController (which contains an array drugs of Drug objects) embedded in a navigation controller.

I am trying to get the appropriate row in the tableview selected when the user taps on a notification.

The code below is successful when the app is open or in background, but does not select the row when the app has been closed when the notification is received (though it still loads the tableview correctly).

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

    // Pull out the buried userInfo dictionary
    let userInfo = response.notification.request.content.userInfo
    if let drugID = userInfo["drug"] as? String {

        let navigationController = self.window?.rootViewController as! UINavigationController
        let destinationViewController = navigationController.viewControllers[0] as! DrugTableViewController
        navigationController.popToViewController(destinationViewController, animated: true)


        var selectRow: Int? = nil
        for drug in destinationViewController.drugs {
            if drug.uniqueID == drugID {
                selectRow = destinationViewController.drugs.index(of: drug)!
                let path = IndexPath(row: selectRow!, section: 0)
                destinationViewController.tableView.reloadData()
                destinationViewController.tableView.selectRow(at: path, animated: true, scrollPosition: .top)
                selectRow = nil
                break
            }
        }
    }
    // Call completion handler
    completionHandler()
}

I have also tried instantiating my detail view controller from the storyboard ID but this does not work.

Any help would be greatly appreciated!


Solution

  • This code may be invoked until table view has beed loaded. Firstly try to delay notification handling for a second: DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: { //Your code here }) and look, will it help or not. If will, think how you can check is tableview has been loaded or not (or just left the delay)