因此,我正在使用路由器设计模式编写网络代码。我正在为应用程序的不同组件编写一个新路由器(我应该这样做吗?我尝试限制我的对象行)。我的路由器枚举。如果我使用的是类,我可以定义一种方法来填充诸如httpmethod之类的变量,并在必要时覆盖它们。有没有办法用枚举来做到这一点?是值得实施的还是我应该重复相同的代码。除了httpmethod(例如URL构造),我认为这可能会有所帮助。我以为我可以通过协议做点什么,但不确定我是否浪费时间。
enum PRRouter: URLRequestConvertible {
static let baseURLString = "http://localhost:8000/"
case get(Int)
case create([String : Any])
case delete(Int)
func asURLRequest() throws -> URLRequest {
var method: HTTPMethod{
switch self {
case .get:
return .get
case .create:
return .post
case.delete:
return .delete
}
}
let params : ([String : Any]?) = {
switch self {
case .get, .delete:
return nil
case .create(let newTodo):
return newTodo
}
}()
let url : URL = {
let relativePath: String?
switch self{
case .get(let number):
relativePath = "test/(number)"
case .create:
relativePath = "test/"
case .delete:
relativePath = "test/"
}
var url = URL(string: PRRouter.baseURLString)!
if let relativePath = relativePath {
url = url.appendingPathComponent(relativePath)
}
return url
}()
var urlRequest = URLRequest(url:url)
urlRequest.httpMethod = method.rawValue
let encoding = JSONEncoding.default
return try encoding.encode(urlRequest, with: params)
}
使枚举符合具有默认实现的协议。
protocol P {
func f()
}
extension P {
func f() { print("default implementation") }
}
enum E: P {
case Foo
}
let e = E.Foo
e.f()
我在自己的项目中做类似的事情。这是一个基于您的代码的示例,可以使您入门:
protocol APIProtocol {
var path: String { get }
var method: HTTPMethods { get }
var bodyParameters: [String: Any?]? { get }
}
enum HTTPMethods: String {
case get = "GET"
case post = "POST"
}
enum PRRouter: APIProtocol {
case get(Int)
case create([String : Any])
case delete(Int)
var path: String {
switch self {
case let .get(number):
return "test/(number)"
default:
return "test"
}
}
var method: HTTPMethods {
return .get
}
var bodyParameters: [String : Any?]? {
return nil
}
}
extension APIProtocol {
func execute(completion: @escaping ((Data?) -> Void)) -> URLSessionDataTask? {
guard let url = URL(string: "http://localhost:8000/(path)") else { return nil }
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = method.rawValue
if let bodyParameters = bodyParameters {
urlRequest.httpBody = try? JSONSerialization.data(withJSONObject: bodyParameters, options: [.prettyPrinted])
}
let task = URLSession.shared.dataTask(with: urlRequest) { (data, urlResponse, error) in
completion(data)
}
task.resume()
return task
}
}
最后您可以这样使用:
let dataTask = PRRouter.get(2).execute { (data) in
//
}
您可以通过更改执行函数中的完成块来进一步扩展此问题。