I practicing networking in Swift and I attempted to make a network layer where each request and its data is in an enum and each request has its own response handler.
However I cannot get past a type error...
This is my code, you can copy and paste it in a playground, it doesn't actually process the request.
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
extension String: Error { }
typealias ResponseHandler = (Data?, URLResponse?, Error?, ResponseHandlerCompletion?) -> ()
typealias ResponseHandlerCompletion = (Result<AnyObject, Error>) -> ()
enum RequestType {
case githubInfo
case googleInfo
var url: URL {
switch self {
case .githubInfo: return URL(string: "https://github.com")!
case .googleInfo: return URL(string: "https://google.com")!
}
}
var completion: ResponseHandler? {
switch self {
case .githubInfo: return NetworkLayer.githubInfoResponseHandler
case .googleInfo: return NetworkLayer.googleInfoResponseHandler
}
}
}
class NetworkLayer {
let session = URLSession(configuration: .default)
func request(_ requestType: RequestType, completion: ResponseHandlerCompletion?) {
let request = URLRequest(url: requestType.url)
session.dataTask(with: request) { (data, response, error) in
requestType.completion?(data, response, error, completion)
}
}
func githubInfoResponseHandler(_ data: Data?, _ response: URLResponse?, error: Error?, _ completion: ResponseHandlerCompletion?) {
print("Processing github response...")
let result: Result<AnyObject, Error> = .failure("...")
completion?(result)
}
func googleInfoResponseHandler(_ data: Data?, _ response: URLResponse?, error: Error?, _ completion: ResponseHandlerCompletion?) {
print("Processing google reponse...")
let result: Result<AnyObject, Error> = .failure("...")
completion?(result)
}
}
let networkLayer = NetworkLayer()
networkLayer.request(.githubInfo) { (result) in
switch result {
case .success(let object):
print(object)
case .failure(let error):
print(error)
}
}
The full error message is:
Cannot convert return expression of type '(NetworkLayer) -> (Data?, URLResponse?, Error?, ResponseHandlerCompletion?) -> ()' (aka '(NetworkLayer) -> (Optional, Optional, Optional, Optional<(Result<AnyObject, Error>) -> ()>) -> ()') to return type 'ResponseHandler?' (aka 'Optional<(Optional, Optional, Optional, Optional<(Result<AnyObject, Error>) -> ()>) -> ()>')
The error appears on these 2 lines:
case .githubInfo: return NetworkLayer.githubInfoResponseHandler
case .googleInfo: return NetworkLayer.googleInfoResponseHandler
So basically the function I'm trying to return is:
(NetworkLayer) -> (Data?, URLResponse?, Error?, ResponseHandlerCompletion?) -> ()
when it is expecting:
(Data?, URLResponse?, Error?, ResponseHandlerCompletion?)
I don't understand where that (NetworkLayer) -> (...) -> ()
comes in? I've never seen a function type like that.
Am I missing something, is there a way to fix and work with this or did I just hit a wall?
I'd appreciate any help.
I know that my code is not exactly good, I have force unwraps and my results are bogus, I was trying to isolate the problem as much as possible.