- Goal
-
-
From Apple’s WWDC 2019 presentation Advances in Networking, Part 1, a sample pattern was provided using
tryCatch
andtryMap
operators to react to the specific error of the network being constrained.
-
- References
- See also
- Code and explanation
// Generalized Publisher for Adaptive URL Loading
func adaptiveLoader(regularURL: URL, lowDataURL: URL) -> AnyPublisher<Data, Error> {
var request = URLRequest(url: regularURL) (1)
request.allowsConstrainedNetworkAccess = false (2)
return URLSession.shared.dataTaskPublisher(for: request) (3)
.tryCatch { error -> URLSession.DataTaskPublisher in (4)
guard error.networkUnavailableReason == .constrained else {
throw error
}
return URLSession.shared.dataTaskPublisher(for: lowDataURL) (5)
.tryMap { data, response -> Data in
guard let httpResponse = response as? HTTPUrlResponse, (6)
httpResponse.statusCode == 200 else {
throw MyNetworkingError.invalidServerResponse
}
return data
}
.eraseToAnyPublisher() (7)
This example, from Apple’s WWDC, provides a function that takes two URLs - a primary and a fallback. It returns a publisher that will request data and fall back requesting a secondary URL when the network is constrained.
-
The request starts with an attempt requesting data.
-
Setting
request.allowsConstrainedNetworkAccess
will cause thedataTaskPublisher
to error if the network is constrained. -
Invoke the
dataTaskPublisher
to make the request. -
tryCatch
is used to capture the immediate error condition and check for a specific error (the constrained network). -
If it finds an error, it creates a new one-shot publisher with the fall-back URL.
-
The resulting publisher can still fail, and
tryMap
can map this a failure by throwing an error on HTTP response codes that map to error conditions -
eraseToAnyPublisher
enables type erasure on the chain of operators so the resulting signature of the adaptiveLoader function isAnyPublisher<Data, Error>
In the sample, if the error returned from the original request wasn’t an issue of the network being constrained, it passes on the .failure
completion down the pipeline.
If the error is that the network is constrained, then the tryCatch
operator creates a new request to an alternate URL.