Home > Net >  Swift - Subclassing URLSessionDataTask - Which super.init(DataTaskFakeWrapper: URLSessionDataTask ??
Swift - Subclassing URLSessionDataTask - Which super.init(DataTaskFakeWrapper: URLSessionDataTask ??

Time:11-16

I'm trying to subclass a URLSessionDataTask as shown in this post Initializer does not override a designated initializer while subclassing NSURLSession Swift Except that the sub class init imposes a super.init back to the parent class. Here is the code :

class DataTaskFakeWrapper {
 let DataTaskFakeWrapper: URLSessionDataTask
  init(DataTaskFakeWrapper: URLSessionDataTask) {
      self.DataTaskFakeWrapper = DataTaskFakeWrapper
 }

}

class DataTaskFake: DataTaskFakeWrapper {
 var completionHandler: ((Data, URLResponse, Error) -> Void)?
 var data: Data
 var urlResponse: URLResponse
 var responseError: Error
 init( data: Data, urlResponse: URLResponse, responseError: Error) {
      self.data = data
      self.urlResponse = urlResponse
      self.responseError = responseError
      super.init(DataTaskFakeWrapper:
                     URLSessionDataTask)
  }
 
 func resume() {
      completionHandler?(data, urlResponse, responseError)
 }
 
 func cancel() {
      // not applicable
 }

}

The message "Cannot convert value of type 'URLSessionDataTask.Type' to expected argument type 'URLSessionDataTask" appears and I can't find the right type to communicate from my sub class :

super.init(DataTaskFakeWrapper:
                     URLSessionDataTask)

and avoid that message : "Cannot convert value of type 'URLSessionDataTask.Type' to expected argument type 'URLSessionDataTask"

With a similar subclassing of URLSession, the super.int allows the URLSession(configuration: .default) argument.

What is the one for URLSessionDataTask in my case. Thanks a lot

CodePudding user response:

  1. Inside the DataTaskFakeWrapper class your DataTaskFakeWrapper property should be typed in camel case so dataTaskFakeWrapper to avoid confusion of being a type itself
  2. Inside the DataTaskFake super.init call you're not initializing the object, just trying to pass the type. Right now it should be
let dataTask = URLSession.shared.dataTask(with: URLRequest(url: URL(string: "https://www.my-fake-url.com")))
super.init(
  DataTaskFakeWrapper: DataTaskFakeWrapper(
    DataTaskFakeWrapper: dataTask
  )
)

This also shows you why it's good to name the property using camel case.

It would also be great to stub the networking code so that your tests are not making real network requests (resulting in flaky results). You can read more about implementing URLProtocol and then registering your "fake server" using URLProtocol.registerClass

  • Related