gpt4 book ai didi

swift - 根据路径更改响应模型/形状

转载 作者:行者123 更新时间:2023-11-30 10:55:49 31 4
gpt4 key购买 nike

我有一个网络层,用于调用多个端点。我想减少重复代码的数量,并认为也许我可以将响应模型作为端点的一部分传递。

这个想法是不需要多个仅因响应而不同的函数,我可以调用我的网络层并根据路径进行设置。

我看到的当前错误是

Var 'responseType' is not a member type of 'IdentityEndpoint'

我希望能够实现这样的目标

mutating func identity(with endpoint: IdentityEndpoint, completion: @escaping (Either<IdentityEndpoint.responseType>) -> Void)

而不是这个

mutating func identity(with endpoint: IdentityEndpoint, completion: @escaping (Either<OAuthToken>) -> Void) 

API客户端

struct APIClient: APIClientProtocol {
var task: URLSessionDataTask = URLSessionDataTask()
var session: SessionProtocol = URLSession.shared
var request: URLRequest?

mutating func identity(with endpoint: IdentityEndpoint, completion: @escaping (Either<IdentityEndpoint.responseType>) -> Void) {
dispatch(endpoint: endpoint, completion: completion)
}
}

extension APIClient {
fileprivate mutating func dispatch<T: Codable>(endpoint: EndpointProtocol, completion: @escaping (Either<T>) -> Void) {
do {
request = try constructRequest(from: endpoint)
guard let request = request else { return }
call(with: request, completion: completion)
} catch {}
}

fileprivate func constructRequest(from route: EndpointProtocol) throws -> URLRequest {
var request = URLRequest(url: route.baseUrl.appendingPathComponent(route.path), cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 10.0)
request.httpMethod = route.httpMethod.rawValue
do {
switch route.task {
case .request(let headers):
addAdditionalHeaders(headers, request: &request)
case .requestParams(let bodyParams, let encoding, let urlParams, let headers):
addAdditionalHeaders(headers, request: &request)
try configureParameters(bodyParams: bodyParams, encoding: encoding, urlParams: urlParams, request: &request)
}
return request
} catch {
throw NSError(domain: "Could not create request task for \(route.task)", code: 0, userInfo: nil)
}
}

fileprivate func configureParameters(bodyParams: Parameters?, encoding: ParameterEncoding, urlParams: Parameters?, request: inout URLRequest) throws {
do {
try encoding.encode(urlRequest: &request, bodyParams: bodyParams, urlParams: urlParams)
} catch {
throw NSError(domain: "Could not configure params for request", code: 0, userInfo: nil)
}
}

fileprivate func addAdditionalHeaders(_ additionalHeaders: HTTPHeaders?, request: inout URLRequest) {
guard let headers = additionalHeaders else { return }
for (key, value) in headers {
request.setValue(value, forHTTPHeaderField: key)
}
}
}

IdentityEndPoint

protocol EndpointProtocol {
var baseUrl: URL { get }
var path: String { get }
var httpMethod: HTTPMethod { get }
var task: HTTPTask { get }
var headers: HTTPHeaders? { get }
}


public enum IdentityEndpoint {
case accessToken(company: String, code: String)

func getDomain(forService service: String) -> URL {
return URL(string: "https://{SERVICE}.foo.bar".replacingOccurrences(of: "{SERVICE}", with: service))!
}
}

extension IdentityEndpoint: EndpointProtocol {
var baseUrl: URL {
return getDomain(forService: "identity")
}

var responseType: Codable {
switch self {
default:
return OAuthToken.self as! Codable
}
}

var path: String {
switch self {
case .accessToken(let props):
return "/auth/realms/\(props.company)/protocol/openid-connect/token"
}
}

var httpMethod: HTTPMethod {
switch self {
case .accessToken:
return .POST
}
}

var headers: HTTPHeaders? {
switch self {
case .accessToken:
return ["Content-Type": "application/x-www-form-urlencoded"]
}
}

var task: HTTPTask {
switch self {
case .accessToken(let props):
return .requestParams(bodyParams: [
"grant_type": "authorization_code", "code": "\(props.code)", "redirect_uri": "homedev://oauth-callback", "client_id": "mobile-home"
], encoding: .jsonEncoding, urlParams: nil, headers: headers)
}
}
}

最佳答案

添加associatedtype到您的EndpointProtocol。然后在 IdentityEndpoint 中指定它,如下所示

protocol EndpointProtocol {
associatedtype ResponseType

...
}

extension IdentityEndpoint: EndpointProtocol {
typealias ResponseType = OAuthToken

...
}

现在您将能够编写

mutating func identity(
with endpoint: IdentityEndpoint,
completion: @escaping (Either<IdentityEndpoint.ResponseType>) -> Void
)

关于swift - 根据路径更改响应模型/形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53961409/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com