dataTaskWithCompletionHandler method

URLSessionTask dataTaskWithCompletionHandler(
  1. URLRequest request,
  2. void completion(
    1. Data? data,
    2. HTTPURLResponse? response,
    3. Error? error
    )
)

Creates a URLSessionTask that accesses a server URL and calls completion when done.

See NSURLSession dataTaskWithRequest:completionHandler:

Implementation

URLSessionTask dataTaskWithCompletionHandler(
    URLRequest request,
    void Function(Data? data, HTTPURLResponse? response, Error? error)
        completion) {
  // This method cannot be implemented by simply calling
  // `dataTaskWithRequest:completionHandler:` because the completion handler
  // will invoke the Dart callback on an arbitrary thread and Dart code
  // cannot be run that way
  // (see https://github.com/dart-lang/sdk/issues/37022).
  //
  // Instead, we use `dataTaskWithRequest:` and:
  // 1. create a port to receive information about the request.
  // 2. use a delegate to send information about the task to the port
  // 3. call the user-provided completion function when we receive the
  //    `CompletedMessage` message type.
  final task =
      URLSessionTask._(_nsObject.dataTaskWithRequest_(request._nsObject));

  HTTPURLResponse? finalResponse;
  MutableData? allData;

  _setupDelegation(_delegate, this, task, onRedirect: _onRedirect, onResponse:
      (URLSession session, URLSessionTask task, URLResponse response) {
    finalResponse =
        HTTPURLResponse._(ncb.NSHTTPURLResponse.castFrom(response._nsObject));
    return URLSessionResponseDisposition.urlSessionResponseAllow;
  }, onData: (URLSession session, URLSessionTask task, Data data) {
    allData ??= MutableData.empty();
    allData!.appendBytes(data.bytes);
  }, onComplete: (URLSession session, URLSessionTask task, Error? error) {
    completion(allData == null ? null : Data.fromData(allData!),
        finalResponse, error);
  });

  return URLSessionTask._(task._nsObject);
}