Using OperationQueue for your URL requests (with a built-in retry mechanism).
Here is the detailed lifespan of an URLRequestOperation
:
First, the URL is processed for running. Which means the method
processURLRequestForRunning
is called. This is an override point for
subclasses if they want to prevent the request to run depending on certain
condition, or if they want to modify the URL Request prior running it.
This processing might take some time, or be expensive resource-wise, which
is why you can specify a queue on which the processing will be done. (This
is the queueForProcessingURLRequestForRunning
property.)
If the processing fails (returns an error), the operation will go to the error processing step (4) with the given error (the operation might be retried later depending on the error processing result).
Next, the session task is created. The creation of the task and the behavior of the operation will differ depending on the delegate of the URL session given to the operation.
Session delegate is an instance of URLRequestOperationSessionDelegate
:
The task is created with urlSessionTaskForURLRequest(_:withDelegate)
(which can be overridden if need be). By default, in this method, the
session delegate is told to forward the delegate method regarding this
specific task to the operation (the delegate of an URL session is a
global delegate and cannot be set by task without this hack AFAIK).
If subclasses overwrite this method and decide to work a different way
for the delegate method, they will be responsible for receiving the data
and treating it, then must call
urlSession(_:task:didCompleteWithError:)
when the task is done.
Session delegate is kind of another class of nil
: The task is created
with the urlSessionTaskForURLRequest(_:,withDataCompletionHandler:, downloadCompletionHandler:)
.
Finally the task is launched.
URLRequestOperationSessionDelegate
:
errorForResponse(_:)
will
check whether the response is appropriate (correct status code and mime
type, or other pre-filters). Then the urlResponseProcessor
will be
called if the previous check passes. Both method can cancel the session
task if they deem the response not worthy of continuing.urlSession(_:task:didCompleteWithError:)
), the task will
finish. processEndOfTask(error:)
(private) is called to check what to
do from here.processEndOfTask(error:)
is called.processEndOfTask(error:)
):
If there is already a final error (eg. operation cancelled), the operation is ended here.
Otherwise the computeRetryInfo(sourceError:completionHandler:)
method is
called on the queueForComputingRetryInfo
(computing the retry info might
be an expensive operation). This method is reponsible for telling whether
the operation should be retried, and after which delay. The default
implementation will check the error. For a network lost for instance, the
operation should be retried for idempotent HTTP requests. The delay
respects an exponential backoff by default. Subclasses can override to
implement their own logic and behavior.
This is actually the most important override point for the operation.
The computeRetryInfo
method will also allow to decide whether some “early
retrying” techniques should be setup. Or you can setup your own. There are
two built-in retrying techniques: The ReachabilityObserver
which will
simply check when the network is reachable again and the Other Success Observer
which will trigger a retry when another URLRequestOperation for
the same host succeeds.
If you decide to write your own “early retrying” methods, you should
overwrite removeObserverForEarlyRetrying()
and remove your observers in
your implementation. Do not forget to call super!
If the operation is told to be retried, when it is retried, we simply go back to step 2. (The URL is re-processed, etc.)
This project was originally created by François Lamboley while working at happn.
link |
Stars: 4 |
Last commit: 2 weeks ago |
Full Changelog: https://github.com/happn-app/URLRequestOperation/compare/1.1.10...1.1.11
Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics