If you’ve done any work with background refresh (application:didReceiveRemoteNotification:fetchCompletionHandler:) on iOS 7 you know that it can be a pain to debug your code with.  Some things I’ve discovered:

  1. Background refresh will start your app if it’s not running.
  2. If you force-quit an application, it’s not eligible to be started by a push notification.  Restarting the app or rebooting is the only way to again receive background push wakes.
  3. You can’t really debug wake by push other than with logging.
  4. Touching UI code in application:willFinishLaunchingWithOptions: is risky with background push since it fires but didFinishLaunchingWithOptions won’t if it’s immediately backgrounded.  If you’re using UIStateRestoration, make sure you’re limiting UI code in willFinishLaunchingWithOptions to setting up the root view controller.
  5. Don’t arbitrarily reset the badge count when your app is presented – you should really reset the badge count when the notification is viewed/considered no longer relevant.
  6. Update your push service to send “all clear” or zero count badges when things are read via other instances of your app (web, other iOS device, Android too).  Your users will thank you that they’re cleared everywhere.

Take a look at Apple’s documentation on app lifecycle – there is an excellent set of graphics to demonstrate where things hook in.