Skip to content

Instantly share code, notes, and snippets.

@LukeSmith16
Last active April 3, 2023 13:55
Show Gist options
  • Save LukeSmith16/4dd881d8c1a97bbe8b64c5adea3c563a to your computer and use it in GitHub Desktop.
Save LukeSmith16/4dd881d8c1a97bbe8b64c5adea3c563a to your computer and use it in GitHub Desktop.
A custom URLProtocol subclass to handle returning mock data for network service requests for UITests
final class UITestConnectionHandler: URLProtocol {
private static var allowedResponses: [URL: MockResponse] = [:]
static func setAllowedResponse(with response: MockResponse) {
allowedResponses[response.url] = response
}
override class func canInit(with request: URLRequest) -> Bool {
// Only return true for requests we want this provider to handle otherwise revert to default
guard let url = request.url else { return false }
return allowedResponses.keys.contains(url)
}
override class func canonicalRequest(for request: URLRequest) -> URLRequest {
return request
}
// You could also introduce an artificial delay and send the data chunks to the client gradually. It’s a great way to simulate bad network conditions.
override func startLoading() {
guard let client, let url = request.url else { fatalError() }
guard let responseProvider = UITestConnectionHandler.allowedResponses[url] else {
fatalError("Failed to set a response provider")
}
switch responseProvider.response {
case .success(let content):
let response = HTTPURLResponse(url: url, statusCode: content.statusCode, httpVersion: nil, headerFields: nil)!
client.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed)
client.urlProtocol(self, didLoad: content.data)
client.urlProtocolDidFinishLoading(self)
case .error(let error):
client.urlProtocol(self, didFailWithError: error)
client.urlProtocolDidFinishLoading(self)
}
}
override func stopLoading() { }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment