Apps in the Background

Apps in the Background

When building an app, a lot of focus and effort is put on crafting the best foreground experience for users. However, our apps also have a hidden life when we move them the background. And the system watchdog is here to make sure they all behave! In this talk, you will learn what the common pitfalls of background execution are, how you can make sure you don’t exceed system resources by applying best practices, and finally, how to optimize network requests when your app is not in the foreground.

52437c5f89bd79f6972762825759cbbf?s=128

Alexis Aubry

April 29, 2019
Tweet

Transcript

  1. Apps in the Background The secret life of apps when

    you minimize them. Alexis Aubry — App Builders 2019 @_alexaubry
  2. Delivering a good UX means More than a foreground experience

  3. Our Plan How do we provide the best experience to

    our users even when they don’t interact with the app? 1. What does it mean to be in the background? 2. What are the common problems and how to detect them? 3. How can we fix these issues and improve the UX?
  4. What does it mean to be in the background?

  5. Possible States Minimized App Push Notification Background Refresh

  6. Moving to the Background applicationWillResignActive(_:) UI Snapshot Suspended applicationDidEnterBackground(_:)

  7. Handling Background Events UI Snapshot Process the events applicationDidEnterBackground(_:) Launch

    if needed Suspended
  8. How to identify issues?

  9. Common Exception Codes • 0x8badf00d = took too long to

    respond to a system event • 0xdead10cc = forgot to release a file lock after suspension • 0xc51bad01 = CPU usage too high in the background • 0xc51bad02 = took too long to move to the background • 0xc51bad03 = system resources too low to continue • 0xbada5e47 = exceeded the limit of background tasks
  10. Other Symptoms • Missing data or expected event not happening

    • Example: taking too long to process a push payload. • Routinely check your crash reports for the aforementioned codes.
  11. Other Symptoms • Unexpectedly high battery usage • If you

    take a lot of time to process events, but stay under the limit, the system will probably not terminate your app. • Example: you can spend 20 seconds for each push notification, under the limit, but will have an impact on user’s battery. • At Wire: reduced background activity by 5 hours a week.
  12. What are the techniques for the best background experience?

  13. Use background tasks 1

  14. ✅ Get more time to complete your background work

  15. How it Works UIApplication Your Code

  16. Starting a Task beginBackgroundTask Your Code Expiration Handler

  17. Starting a Task beginBackgroundTask Your Code Expiration Handler

  18. Starting a Task beginBackgroundTask Your Code Expiration Handler Task Identifier

  19. Check for Expiration beginBackgroundTask Your Code Expiration Handler .invalid

  20. Performing your work UIApplication Task Identifier Expiration Handler Async Queue

    Your Background Work
  21. Finishing your work endBackgroundTask Your Code Expiration Handler Task Identifier

  22. Expiring Properly endBackgroundTask Your Code Expiration Handler Task Identifier

  23. For App Extensions ProcessInfo.processInfo.performExpiringActivity(withReason: "Request") { [weak self] expiring in

    guard let self = self else { return } if expiring { // Clean up your code before suspension self.currentRequest?.cancel() } else { // Otherwise perform the task let request = self.networkingLayer.createRequest() self.currentRequest = request request.resume() } }
  24. When to Use It • Every time interrupting the work

    would be detrimental to the UX • Example: when sending a message or saving a file. • When operating in the foreground • Example: asking for extra time to send a message before going in the background, so you don’t need to care about the state of the app. • Caveat: having too many active background tasks can cause a crash
  25. How to Optimize It • Give names to tasks when

    creating them. • Create all your tasks from a single thread. • Centralize the tasks creation inside one object.
  26. Benefits of a Task Manager • Manages a single background

    task to keep the app awake. • Avoids repeated overhead of creating background tasks. • Avoids issues with gaps between tasks. • Avoids issues with needing to create tasks from multiple threads.
  27. Building a Task Manager BackgroundTasksManager UIKit Your Code

  28. Building a Task Manager beginBackgroundTask UIKit Your Code

  29. Building a Task Manager BackgroundTasksManager Begin task with UIKit Your

    Code No Internal Background Task
  30. Building a Task Manager BackgroundTasksManager Save the token of the

    custom task When we have an Internal Background Task UIKit
  31. Building a Task Manager endBackgroundTask UIKit Your Code After ending

    your work
  32. Building a Task Manager When there are no more active

    tasks BackgroundTasksManager End the internal task Your Code
  33. Building a Task Manager BackgroundTasksManager Expire all active tasks When

    the extended lifetime expires UIKit expiration callback
  34. Building a Task Manager BackgroundTasksManager End the internal task Your

    Code When the extended lifetime expires
  35. Building a Task Manager BackgroundTasksManager Expire immediately When creating tasks

    while the app is expiring UIKit cannot start a real task
  36. Implementation on GitHub github.com/alexaubry/background-tasks-manager

  37. Keep your memory usage under control 2

  38. Reducing Memory Usage • Makes the system more likely to

    keep your app suspended for a longer period of time. • Example: Use a purgeable cache with a disk counterpart. • Example: Reduce your use of images. • Recommended Reads • https://developer.apple.com/library/archive/technotes/tn2434/_index.html • http://www.thomashanning.com/building-memory-efficient-apps/
  39. Use the right API for the right task 3

  40. Using the Right API • Processing notifications in the background?

    • Use a notification service extension. • Downloading files in the background? • Use a background URLSession with sessionSendsLaunchEvents. • https://developer.apple.com/documentation/foundation/ url_loading_system/downloading_files_in_the_background
  41. Design for immediately cancellable tasks and restoration 4

  42. “Apps must be prepared for
 termination to happen at any

    time.”
  43. Architecture Tips • Don’t wait for the user to close

    the app to save data. • Make every task cancellable, so that you can stop them during expiration. • Design background behavior with UX in mind. • Example: if we cancel sending a message, how do we communicate that to the user?
  44. What should happen if we cancel a running task? Is

    it recoverable? Does it need user interaction to recover?
  45. Wrapping Up • Different scenarios, different rules. • Comply to

    stay frozen in the background as long as possible. • Look for the signs to detect potential bottlenecks. • Use background tasks as often and efficiently as possible. • Use the latest APIs and tools to optimize background work. • Design for immediately cancellable tasks, think about the UX.
  46. Thank you! Questions? Tweet me @_alexaubry