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.

Agnes Vasarhelyi

August 27, 2018
Tweet

More Decks by Agnes Vasarhelyi

Other Decks in Programming

Transcript

  1. SUMMARY OF THIS TALK Handling background transfers ⏰ Silent (content)

    push notifications Authentication Resume rate limiter % Testing Debugging
  2. REMINDER "Background apps that consume large amounts of memory are


    terminated before those with small memory footprints." Source: developer.apple.com
  3. 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
  4. HANDLING BACKGROUND TRANSFER isDiscretionary "For time-insensitive tasks, enable the isDiscretionary

    property, so the system can wait for optimal conditions..." Source: developer.apple.com
  5. 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
  6. ⏰ 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
  7. ⏰ 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
  8. ⏰ SILENT (CONTENT) PUSH NOTIFICATIONS "The system tracks the elapsed

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

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

    notifications received • Time executing in the background • Resources used (power, memory)
  11. 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: $$$
  12. AUTHENTICATION 2. Authentication challenges ⚠ • HTTP Basic, HTTP Digest

    • Easier to implement on both client / server • Too many resumes
  13. 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
  14. 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
  15. RESUME RATE LIMITER download task Papp Pnsurlsessiond ACTIVE BACKGROUND SUSPENDED

    temporary file URL BACKGROUND BACKGROUND SUSPENDED authentication challenge ⏳
  16. 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
  17. 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
  18. RESUME RATE LIMITER How to make the rate limiter happy?

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

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

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

  22. 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
  23. Why Must Not Proceed? • An active app downloading? •

    Not the time of the day? • Got enough background downloading for the hour?
  24. 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