Confusion between background vs suspended app states

You should look in the IOS App Programming Guide section "App States and Multitasking". Find that by searching the Xcode documentation with the phrase "App States and Multitasking" and "Hits Must" item set to "Match Search Term". Another useful search phrase: "background execution".

The summary answer is that an application can continue "executing" in the background indefinitely for only a limited number of reasons:

in iOS, only specific app types are allowed to run in the background:

  • Apps that play audible content to the user while in the background, such as a music player app
  • Apps that keep users informed of their location at all times, such as a navigation app
  • Apps that support Voice over Internet Protocol (VoIP)
  • Newsstand apps that need to download and process new content
  • Apps that receive regular updates from external accessories

Aside from those specific operations, an app can ask to continue to execute for a very short time which the documentation covers in the section "Executing a Finite-Length Task in the Background". After a short time either your app tells the system it is done (and is then suspended) or it is forcibly terminated. Details in the doc.

Another useful bit of that document, with nice state diagrams, is the section "Managing App State Changes". That section talks about going into the background and returning to the foreground. It should answer your question about the difference between starting fresh versus starting from the suspended state. The short (not quite correct) answer is that if you start from the suspended state and you don't take any special actions when entering the background or (re)entering the foreground then you just continue more-or-less from where you were. Also, starting from the suspended state is faster. Read the doc since it says it much better than my paraphrase would.


App State

Not running: Your app is in this state before it starts up.

Active: Once your app is started, receiving events.

Inactive: When your app is running but something happens to interrupt it, like a phone call, it becomes inactive. Inactive means that the app is still running in the foreground but it’s not receiving events.

Backgrounded: In this state, your app is not in the foreground anymore but it is still able to run code.

Suspended: Your app enters this state when it’s no longer able to run code.


Background:

  • Executing code - Code is executed while the app is in a background state.
  • An app must go into a background state before it can go into a suspended state.
  • ie. Suppose you're on Facebook and you upload a video and you quickly switch to another app immediately after pressing the POST button. Although you switched to another app w/o terminating the app, the app can be configured to perform background processes to complete the upload.
  • An app that is in background does not necessarily mean it is suspended but an app that is suspended is in background.
  • An app can request to stay in background mode for extra time (for purposes of playing audio in the background or completing a network request, for example); afterward it will either go to suspended state or it will be forcibly terminated by the system.

Suspended:

  • Not executing code - Code is not executed while the app is in a suspended state.
  • An app that is in a suspended state is also in a background state.
  • The system moves apps to this state w/o notifying you beforehand.
  • An app in a suspended state is still in memory.

Some additional information that may help you on this topic:

  • UIApplication notifies the app of state transitions through methods in the AppDelegate.
    Most state transitions are accompanies by these methods.
    These methods are part of the UIApplicationDelegate protocol.
    They provide you with a chance to respond to state changes.

    The method below, for example, tells the delegate when the app is about to terminate.
    - It's only called if the app's in background before being terminated; not suspended.

    func applicationWillTerminate(_ application: UIApplication) { ... }

  • In addition to Charlie Price's answer from 2013, iOS now also allows background for:

    • REMOTE NOTIFICATIONS that signal there is new content available for download. When a remote notification arrives, the system launches or resumes the app in the background and gives it a small amount of time to download the new content.
    • CORE BLUETOOTH to communicate with a bluetooth accessory while in background.
    • Click here for more details
  • UIApplication.shared.backgroundTimeRemaining tells you how many seconds is remaining until the system terminates the application. 3 minutes is the maximum time limit, but this time restarts each time the app is woken up in background mode.

  • You can prevent your app from ever entering a background or suspended state & instead immediately terminating by setting the UIApplicationExitsOnSuspend key to YES in the info.plist.

  • Additional links you may find useful:

    • https://developer.apple.com/library/archive/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
    • https://developer.apple.com/documentation/uikit/core_app/managing_your_app_s_life_cycle/preparing_your_app_to_run_in_the_background/about_the_background_execution_sequence

    • https://medium.com/@abhimuralidharan/finite-length-tasks-in-background-ios-swift-60f2db4fa01b

    • https://qph.fs.quoracdn.net/main-qimg-473264d5d9f0ec16d57b8dffcc9824d8