iOS Background Modes

iOS supports a number different modes for background execution:

Location Updates

  • This allows your app to receive updates when the location changes.
  • More interestingly, these three types of location updates can relaunch your app after backgrounding/termination to deliver notification updates.
    • Significant-change location service
    • Visits service
    • Geofences / region monitoring
  • To see what this looks like in practice:
    class ViewController: UIViewController, CLLocationManagerDelegate {
      var location: CLLocationManager = CLLocationManager()
        
      override func viewDidLoad() {
          super.viewDidLoad()
          location.delegate = self
          location.allowsBackgroundLocationUpdates = true
          location.showsBackgroundLocationIndicator = true
          location.pausesLocationUpdatesAutomatically = false
          location.startMonitoringSignificantLocationChanges()
      }
    
      func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
          print("Got location!")
      }
    }
    
    class AppDelegate: UIResponder, UIApplicationDelegate {
      func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
          let session = URLSession.shared
          let url = URL(string: "http://localhost:9990")!
          let task = session.dataTask(with: url, completionHandler: { data, response, error in
          })
          task.resume()
          return true
      }
    }
    
    • And start a local webserver that is notified when didFinishLaunchingWithOptions is called:
      $ python3 -m http.server 9990 --bind 127.0.0.1
      
    • This setup lets you monitor things after app termination (at which point XCode stops displaying logs).
    • A couple of Info.plist changes are required too:
      <key>NSAppTransportSecurity</key>
      <dict>
          <key>NSAllowsArbitraryLoads</key>
          <true/>
      </dict>
      <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
      <string>Test Description</string>
      <key>NSLocationWhenInUseUsageDescription</key>
      <string>Test Description</string>
      
  • I tested this against the “significant-change location” service, which sends out updates roughly every 30s (using the “Freeway Drive” simulator preset).
  • These updates continue to occur when the app is backgrounded and (more importantly) even when it’s terminated.
Edit