3

The app receives a UILocalNotification, but if the user is at the UITableViewController at the fire time, the table view (containing the scheduled notifications) does not reload. The user has to get out of that view and load the view again so that the cells are loaded and, as the notification was already fired, it will not be displayed on any cell of that table view.

Problem is: If the user touches the specific tableView cell that contained the notification that just fired, the app crashes, cause the notification is not there anymore.

I've implemented the - (void)reloadData in every place possible, and it still doesn't load in real time.

What would be a better solution for this?

Other detail, how can I push a specific view after the notification is displayed (when the user slides the app icon when the phone is locked)?

Any help will be truly appreciated, since theres are the last details remaining to publish my first App.

Lorenzo B
  • 33,216
  • 24
  • 116
  • 190
  • when you say reloadData is implemented in every possible place, it's not clear what you mean. inside of the TableViewController subclass you are implementing, in the code that accepts the notification, i would expect you should only have to perform a [self.tableView reloadData] to get what you want. do you have code you can share? – john.k.doe Jun 24 '12 at 09:08
  • Could you explain the nature of your crash? – Lorenzo B Jun 24 '12 at 09:12
  • @AlbrahimZ Let me explain it better: I have a tableview that is populated by future UILocalNotifications. If a notification fires, the tableview automatically dismiss one cell (the cell used to display that specific notification that fired at this moment). But its not reloading if I am currently IN the tableview controller. If I go back to the main view and load the tableview again, it will be refreshed normally. I want it to refresh in real time, as soon as the notification fires, even if the user is currently viewing his future notifications. – Lucas Vallim da Costa Jun 24 '12 at 09:47
  • So, if i have a notification scheduled, for example, for 1 minute from now, and i decide to view my future notifications, I would open that tableview. BUT, if the local notification fires while I'm in the tableview, it won't refresh, it will say i still have that notification scheduled. To be updated, i have to get out of the view and load the tableview again – Lucas Vallim da Costa Jun 24 '12 at 09:49

1 Answers1

1

The problem you describe is caused by the current local notification: While the notification is handled, it is still in the list of scheduled notifications, so refreshing the table view will have no effect. A solution to this problem is to defer reloading the table view until after the notification is handled, something like

// In your app delegate
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.localNotificationsController reloadDataIfNeeded];
    });
}

// In your controller that shows the local notifications
- (void)reloadDataIfNeeded
{
    if (![self isViewLoaded]) return;

    [self.tableView reloadData];
}

You could also delete the notification from the list if you only use notifications that only fire once (so that you are sure that the notification will disappear anyway):

// In your app delegate
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    [application cancelLocalNotification:notification];
    [self.localNotificationsController reloadDataIfNeeded];
}

As to the second part of your question ("how can I push a specific view after the notification is displayed (when the user slides the app icon when the phone is locked?"), there are two scenarios how an application can be activated by a local notification.

  1. Your application was suspended, but still in memory. Then selecting the local push notification will make the app enter the foreground, -application:didReceiveLocalNotification: will be called, and [application applicationState] will be UIApplicationStateInactive
  2. Your application is not running, i.e. not suspended, not in memory. Then you will receive the local notification in the launchOptions in -application:didFinishLaunchingWithOptions::

    UILocalNotification *localNotification = [launchOptions valueForKey:UIApplicationLaunchOptionsLocalNotificationKey];
    

    Despite what the documentation says, -application:didReceiveLocalNotification: will not be called in this case.

So to show the notification that woke up the application, you can push your controller in these two cases.

Tammo Freese
  • 10,514
  • 2
  • 35
  • 44