我正在探索 GraphQL(这对我来说是新的)。我想进行经过身份验证的呼叫,但由于某种原因,它似乎没有发送:Proxyman 没有显示任何内容,并且我没有收到错误。
我遵循了官方教程并复制/改编了大部分代码。
相关代码:
public final class Network {
public static let shared = Network()
public static func authenticatedApollo(_ authenticationData: GraphQLAuthenticationData) -> ApolloClient {
let client = URLSessionClient()
let cache = InMemoryNormalizedCache()
let store = ApolloStore(cache: cache)
let provider = NetworkAuthenticatedInterceptorProvider(client: client, store: store, authenticationData: authenticationData)
let url = URL(string: "my instance url")!
let transport = RequestChainNetworkTransport(interceptorProvider: provider, endpointURL: url)
return ApolloClient(networkTransport: transport, store: store)
}
}
private class AuthorizationInterceptor: ApolloInterceptor {
public var id: String
private let authenticationData: GraphQLAuthenticationData
init(id: String = UUID().uuidString, authenticationData: GraphQLAuthenticationData) {
self.id = id
self.authenticationData = authenticationData
}
func interceptAsync<Operation>(chain: RequestChain,
request: HTTPRequest<Operation>,
response: HTTPResponse<Operation>?,
completion: @escaping (Result<GraphQLResult<Operation.Data>, Error>) -> Void)
where Operation: GraphQLOperation {
request.addHeader(name: "Authorization", value: authenticationData.token)
// adding other headers
chain.proceedAsync(request: request, response: response, interceptor: self, completion: completion)
}
}
private class NetworkAuthenticatedInterceptorProvider: DefaultInterceptorProvider {
private let authenticationData: GraphQLAuthenticationData
init(client: URLSessionClient = URLSessionClient(), shouldInvalidateClientOnDeinit: Bool = true, store: ApolloStore, authenticationData: GraphQLAuthenticationData) {
self.authenticationData = authenticationData
super.init(client: client, shouldInvalidateClientOnDeinit: shouldInvalidateClientOnDeinit, store: store)
}
override func interceptors<Operation>(for operation: Operation) -> [ApolloInterceptor] where Operation: GraphQLOperation {
var interceptors = super.interceptors(for: operation)
let interceptor = AuthorizationInterceptor(authenticationData: authenticationData)
interceptors.insert(interceptor, at: 0)
return interceptors
}
}
执行查询时,我没有收到成功或失败消息:
Network.authenticatedApollo(authenticationData).fetch(query: DemoAuthenticatedCallQuery(), cachePolicy: .fetchIgnoringCacheData) {result in
switch result {
case .success(let data):
print("🛸 authenticated data: <...>)")
case .failure(let error):
print("🛸 authenticated error: \(error.localizedDescription)")
}
}
但是如果我添加断点,我会看到我的拦截器被添加到 NetworkChain 列表中。我还验证了代码生成似乎运行良好。
欢迎任何相关提示!
我想通了。上述方法的问题是内存管理之一......
仅从函数返回
ApolloClient
不足以充分保留客户端,它会在发送请求之前超出范围。需要明确的是,我的示例中 Apollo 客户端的范围是进行调用的函数。
在结构中创建属性(如
private var apollo: ApolloClient?
)可以纠正此问题,并且客户端在请求的整个持续时间内保留在内存中。
希望这对某人有帮助。