Download
Eric Kinnear: Hi, my name is Eric
from the Internet Technologies team.
Today, we'll cover how your app can adapt
to changing network conditions.
We'll dive right in by looking at different types of networks
and their unique properties.
We'll cover how to use APIs available on Apple platforms
to describe your networking needs to the system.
When things don't work right away, we'll explore how your app
can know when to try connecting again.
And finally, we'll dig into testing
under a variety of network conditions
to make sure that everyone using your app
has the best experience possible.
Let's start by talking about networks.
Apple devices often have multiple ways to connect
to a network, for example, cellular networks or Wi-Fi.
If the device just has a cellular connection,
internet traffic can, of course, use that interface.
Once the device joins a Wi-Fi network,
you might be tempted to think that Internet traffic
will just use that interface instead.
However, now the device has
at least two different interfaces it can use.
Some protocols and apps can use either,
or even both of these interfaces at the same time.
Existing connections may see a better route notification,
indicating that they should consider
using a new connection for subsequent communication.
For example, apps can use multipath technologies
such as multipath TCP and QUIC to create connections
that seamlessly migrate between cellular and Wi-Fi
if connectivity is lost.
Apps can also use 5G networks instead of Wi-Fi
when conditions would make it a better experience.
Networks have different properties.
making them suitable for different types of use.
For example, some cellular networks
may be expensive to use, with metered data plans,
while others may be unlimited.
Some Wi-Fi networks, similarly, should not be used
for bulk data, like when connected to Personal Hotspot.
Someone may have put their connection into Low Data mode,
a signal that they want to limit their data use.
Other network resources may only be available after the system
does work to bring up another interface, like VPN.
iPhone or iPad might even have an Ethernet connection
available to apps as well.
These are just a few examples of the many different types
of connectivity that may be available to a device.
Fortunately, your app does not need to account for all
of these different combinations to create the best experience.
Apple platforms intelligently select the best interface
for your app's connections.
To get the most out of this, you just need to describe
your app's networking needs to the system.
Let's explore how to do that.
The best way to account for all of these network types
is to reason about the properties of the network,
rather than the type of the network.
This lets the system select the best interface
in any of these combinations for your app's connection.
There are two properties of a network
that you can use to declare your networking needs.
Using just these two properties, your app can respect
user preferences for how they want apps
to use available networks.
Constrained networks arise when someone has requested
that apps use less data by enabling Low Data mode
and is automatically enabled for Personal Hotspot.
Use allowsConstrainedNetworkAccess
on URLSessionConfiguration, and prohibitsConstrainedPaths
when using network framework to determine whether
a connection should proceed on a constrained network.
In general, apps should limit transfers to small payloads and
only perform tasks that enable the user's explicit actions
when on a constrained network.
Bulk transfers and background prefetching
should not be performed on constrained networks.
Networks can also be expensive to use.
Similar logic applies here.
These networks should only be used for user-initiated work.
Similar APIs in URLSession and NetworkFramework
let you allow or prohibit using these networks.
Consider using similar logic
for both constrained and expensive networks.
Now that you've described the kind of network
your connection should use based on its properties,
you should just try to connect right away.
You may be tempted to check whether the device
is on Wi-Fi or has access to VPN
before you make your connection, but that should be avoided.
Network conditions change frequently, and these changes
can even be triggered by your app's requests.
That means that pre-flight checks are often incorrect
and can lead to unintended behavior in your app.
In fact, pre-flight checks with SCNetworkReachability
are deprecated in iOS 17.4.
Instead, try to connect.
If the system can't immediately fulfill the request
due to current network conditions,
using waitsForConnectivity on your URLSessionConfiguration
or the waiting state on your NW connection
means it will notify you that your task is waiting,
and the system will automatically retry the request
when conditions change.
Because the system can wait for connectivity automatically,
this makes it really easy to know when to try requests again.
Let's explore what to do in this situation.
If the system can't immediately start a network request
when using waitsForConnectivity,
the request will be placed in a waiting state,
and the app will be notified through its urlSession
task delegate that the task is waiting for connectivity.
In this case, you don't have to retry the request again
when connectivity changes.
The system does it automatically.
When a task is waiting for connectivity,
consider communicating the reason to help the user
understand and take any necessary actions,
and provide a way for people to continue using your app.
In this example, the app's data will sync automatically
when the device has connectivity to a nonconstrained network.
However, tapping Sync Now will relax this constraint
and perform a sync on their constrained network.
When communicating network conditions,
use alerts sparingly.
Alerts communicate important information,
but they can be disruptive and confusing
since network conditions are often out of someone's control.
Instead, offer information and options
in line with clear and easy ways to proceed.
Finally, let's talk about testing.
People will experience a variety of different network conditions
when using your app,
so testing many different conditions is essential.
You can simulate different network conditions with Xcode
right in the Devices and Simulators window.
For example, you can select the network link condition
and LTE profile, which will simulate
a typical LTE network in average conditions.
You can then test workflows in your app
to make sure everything is smooth and fluid.
To test your app on an iPhone or iPad, you can use
the Network Link Conditioner in Developer Settings.
Here you can simulate the same network conditions as in Xcode.
And you can use Network Override to simulate changes
of the device's network properties.
Well, you can always use the settings for each interface
to enable Low Data mode.
Here you can set whether the cellular
and the Wi-Fi interfaces on the system
are considered expensive or inexpensive.
You can also configure the system to prefer a 5G network
over poor or insecure Wi-Fi.
This allows you to find situations
where legacy networking code might not be able
to take advantage of better connectivity.
The good news is, as long as the app follows
the best practices we just covered,
and is describing its needs
to Network Framework and urlSession,
the system will intelligently select the best interface
without any extra work.
Now is a great time to adopt modern networking practices
that take advantage of all of the device's network interfaces.
To do this, describe your networking needs to the system
in terms of properties, like whether the request
is suitable for constrained networks.
Avoid limiting requests to specific interfaces,
like Wi-Fi or cellular.
Remove pre-flight networking checks in your app,
and use waitsForConnectivity instead of manual retries
so that your networking resumes automatically
when conditions meet your app's needs.
You should also ensure your app is using
modern and fast protocols, like HTTP/3 and QUIC.
To learn more, watch
"Accelerate Networking with HTTP/3 and QUIC."
With this approach, your app's networking
will adapt to changing network conditions automatically,
and provide the best experience possible.
Thanks for watching.