Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The complicated life of a backgrounded iOS app (360|iDev '18)

The complicated life of a backgrounded iOS app (360|iDev '18)

Background transfer is an invaluable feature if your app is relying on any critical network operation that could potentially drive your user’s attention away when running long, or being interrupted.

There are non-trivial challanges to solve before being able to support it in your apps though. Including limitations around authentication methods, response/error handling, and keeping the mysterious resume rate limiter happy.

After solving this puzzle with some pieces under-documented, almost impossible to debug and nerve-wracking to test, I’m here to share all our findings to help you understand and work comfortably with background sessions.

6190e163993110536deb0767f9f63fdb?s=128

Agnes Vasarhelyi

August 27, 2018
Tweet

Transcript

  1. THE COMPLICATED LIFE OF A BACKGROUNDED iOS APP Agnes Vasarhelyi

    @vasarhelyia
  2. WHY DO ANYTHING IN THE BACKGROUND?

  3. None
  4. SUMMARY OF THIS TALK Handling background transfers ⏰ Silent (content)

    push notifications Authentication Resume rate limiter % Testing Debugging
  5. REMINDER App states Source: developer.apple.com

  6. REMINDER "Background apps that consume large amounts of memory are


    terminated before those with small memory footprints." Source: developer.apple.com
  7. HANDLING BACKGROUND TRANSFER Completion handler-based Delegate-based URLSession API

  8. HANDLING BACKGROUND TRANSFER download task Papp Pdaemon ACTIVE BACKGROUND SUSPENDED

    temporary file URL BACKGROUND
  9. HANDLING BACKGROUND TRANSFER Surprises
 • Storing session IDs • Storing

    completion handler • Tasks are not failing • Users can directly turn off background transfer capability • isDiscretionary might be treated as true
  10. HANDLING BACKGROUND TRANSFER isDiscretionary "For time-insensitive tasks, enable the isDiscretionary

    property, so the system can wait for optimal conditions..." Source: developer.apple.com
  11. HANDLING BACKGROUND TRANSFER isDiscretionary "...if the transfer is initiated while

    the app is in the background,
 ... isDiscretionary property is treated as being true." Source: developer.apple.com
  12. None
  13. ⏰ SILENT (CONTENT) PUSH NOTIFICATIONS Silent push • Silent push

    with content-available flag set • App gets resumed in the background • Limited time window to execute (30 s) • No user permission necessary • Very similar to background fetch
  14. ⏰ SILENT (CONTENT) PUSH NOTIFICATIONS Surprises • User can directly

    switch it off (Settings / Background Refresh) • Rate limited by APNS • No more than 2, or 3 per hour • Won't receive it when app was terminated
  15. ⏰ SILENT (CONTENT) PUSH NOTIFICATIONS "The system tracks the elapsed

    time, power usage, and data costs..." Source: developer.apple.com
  16. ⏰ SILENT (CONTENT) PUSH NOTIFICATIONS "Apps that use significant amounts

    of ... may not always be woken up..." Source: developer.apple.com
  17. ⏰ SILENT (CONTENT) PUSH NOTIFICATIONS What counts? • Number of

    notifications received • Time executing in the background • Resources used (power, memory)
  18. AUTHENTICATION Client trust validation Server trust validation

  19. AUTHENTICATION 1. Certificate pinning ⚠ • Can be simple, and

    secure • No self-signed certificates in the background • Only system-trusted CA-signed certs (ATS req) • Rolling certs: public key has to be static, backup keys • Long-living certs: $$$
  20. AUTHENTICATION 2. Authentication challenges ⚠ • HTTP Basic, HTTP Digest

    • Easier to implement on both client / server • Too many resumes
  21. AUTHENTICATION 3. Custom authentication scheme • Ask for token in

    a foreground session • Authenticate that request, no matter how • Use that token with the background session requests • Server evaluates that • Expire the token
  22. None
  23. RESUME RATE LIMITER download task Papp Pdaemon ACTIVE BACKGROUND SUSPENDED

    temporary file URL BACKGROUND
  24. RESUME RATE LIMITER nsurlsessiond • delay that doubles with each

    resume • delay resets to 0 when user activates app • delay resets to 0 when delay elapsed without new task • applies to your app as a whole, not per session
  25. RESUME RATE LIMITER download task Papp Pnsurlsessiond ACTIVE BACKGROUND SUSPENDED

    temporary file URL BACKGROUND BACKGROUND SUSPENDED authentication challenge ⏳
  26. RESUME RATE LIMITER 1 download 1 resume No custom authentication

    challenge 2 resumes 1 download 2n resumes n downloads Custom authentication challenge = delay * 1 = delay * 2 = delay * 22n n resumes n downloads = delay * 2n
  27. RESUME RATE LIMITER download task A Pnsurlsessiond Papp ACTIVE temporary

    file URL A BACKGROUND ⏳ BACKGROUND auth challenge A SUSPENDED isDiscretionary = true download task B ⏳ * 2 SUSPENDED SUSPENDED ⏳ * 4 BACKGROUND auth challenge B temporary file URL B BACKGROUND BACKGROUND SUSPENDED
  28. RESUME RATE LIMITER How to make the rate limiter happy?

    • Batch the transfers • Authentication that doesn't require additional resumes
  29. RESUME RATE LIMITER No custom authentication challenge 1 resume [n

    downloads] = delay * 1 Custom authentication challenge n + 1 resumes [n downloads] = delay * 2n + 1
  30. None
  31. % TESTING Surprises • Free pass for Xcode builds (RRL

    delays, isDiscretionary) • APNS device token only valid in specific environment • Call registerForRemoteNotifications on every launch
  32. %

  33. DEBUGGING Console.app 1. Look at nsurlsessiond logs for networking 2.

    Look at dasd logs for scheduling 3. Search for your bundle ID 4. Put the pieces together
  34. None
  35. None
  36. None
  37. None
  38. None
  39. None
  40. None
  41. None
  42. None
  43. None
  44. None
  45. None
  46. None
  47. None
  48. Why Must Not Proceed? • An active app downloading? •

    Not the time of the day? • Got enough background downloading for the hour?
  49. None
  50. Tips for implementing background transfer • Only use it for

    time-insensitive work • Design your networking in a way that pleases the RRL • Same goes for authentication • Master the usage of Console.app
  51. Thank you! 
 
 
 
 
 
 
 


    @vasarhelyia
  52. Some useful links
 
 https://developer.apple.com/documentation/uikit/core_app/managing_your_app_s_life_cycle/ preparing_your_app_to_run_in_the_background https://www.nowsecure.com/blog/2017/06/15/certificate-pinning-for-android-and-ios-mobile- man-in-the-middle-attack-prevention/
 https://forums.developer.apple.com/message/42352#42352 https://forums.developer.apple.com/thread/28713


    https://developer.apple.com/documentation/foundation/url_loading_system/ downloading_files_in_the_background https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application