MacKuba

Kuba Suder's blog on Mac & iOS development

Advances in Networking, Part 1

Categories: Foundation, WWDC 19 0 comments Watch the video

Low Data Mode

User preference to minimize data usage

Can be set in the cellular menu and for each WiFi network separately

What it changes:

  • disables background app refresh
  • defers all discretionary background URL sessions
  • tells apps that they should use less data (it’s up to them to take this setting into account)

If you can save data without affecting user experience, then always do this regardless of this setting

Low data mode signals to your app that you should make some tradeoffs if you can save even more data while providing slightly worse experience

What you can do to save data:

  • reduce image quality
  • do less prefetching
  • synchronize less often
  • mark background tasks as discretionary, run URL tasks in the background
  • disable auto-play

But: do not block any user-initiated work, don’t ask for confirmation

URLSessionConfiguration.allowsConstrainedNetworkAccess

URLSessionRequest.allowsConstrainedNetworkAccess

  • if set to false, this tells the system that these requests should not go through if low data mode is on
  • in this case you’re going to get error.networkUnavailableReason == .constrained, and then you should try some other strategy (e.g. fetch a smaller resource)

Network framework: NWParameters.prohibitConstrainedPaths, NWPath.isConstraint (handle updates to the path later)

“Expensive” networks (allowsExpensiveNetworkAccess): no user-visible setting, should (usually) be set to true for any cellular network and WiFi when connected to a mobile hotspot

Use this property instead of checking explicitly if the connection is cellular, it will be more future-proof

Combine & Networking

DataTaskPublisher:

session.dataTaskPublisher(for: request)

Web sockets

let task = URLSession.shared.webSocketTask(with: URL(…))

task.send(.string(“Hello”))
task.receive { … }

In Network framework: both client and server support

Use NWProtocolWebSocket.Options() in parameters to NWConnection, create a listener using NWListener

Mobility improvements

iOS 7  ⭢  Siri using multipath TCP (requires server-side support, so can’t be enabled globally)

iOS 9  ⭢  WiFi assist – falling back to cellular if connection can’t be established on WiFi (but once it’s connected, it stays there)

iOS 11  ⭢  Multipath API available in the SDK

“We believe users should never have to turn off WiFi when they are walking out of their home”

WiFi signal is not consistently spread in all directions – it depends on what objects are behind you and the access point, and sometimes going a meter away can make a big difference

It’s hard to predict where the signal will be good just based on distance, so it’s a big challenge to decide in a predictable way when to use WiFi and when to fall back to cellular

Improved WiFi assist – cross-layer mobility detection – all components of the system provide the necessary information: WiFi and cellular hardware continuously provide information about the signal quality, Network framework and URLSession provide information about the status of requests

→ leads to improved flow recovery

Even when a flow has been established on WiFi and has started exchanging data, if later on the signal is reduced, iOS can decide to move the next request to cellular instead. So the result should be much rarer cases of applications getting stuck trying to load data over a bad WiFi

Do not try to predict which network the request is going to go through by doing a preflight using SCNetworkReachability, because now this can change ay any moment

Apple is now using multipath TCP in: Maps, Apple Music streaming

If you want to use it yourself, see multipathServiceType in URLSessionConfiguration. Useful in particular for services that users are likely to often be using while they’re leaving their home.