如何在Apollo GraphQL:iOS中添加header

krcsximq  于 2023-11-19  发布在  iOS
关注(0)|答案(9)|浏览(165)

Hy我在一个项目中使用Apollo GraphQL方法,它工作正常。但现在客户端需要使用Apollo API添加额外的头。但添加头后,API的响应返回为 unAuthorized
我添加了标题,

  1. let apolloAuth: ApolloClient = {
  2. let configuration = URLSessionConfiguration.default
  3. // Add additional headers as needed
  4. configuration.httpAdditionalHeaders = ["Authorization" : self.singleTonInstance.token]
  5. configuration.httpAdditionalHeaders = ["channel" : "mobile"]
  6. let url = URL(string: "http://xxx/graphql")!
  7. return ApolloClient(networkTransport: HTTPNetworkTransport(url: url, configuration: configuration))
  8. }()

字符串
任何人都可以帮助我了解如何使用Apollo GraphQL添加标题。

bwntbbo3

bwntbbo31#

更新:“Apollo Client v0.41.0”和“Swift 5”解决方案

我在使用Apollo Client v0.41.0和Swift 5.0时也遇到了同样的问题,但上述解决方案都不起作用。经过几个小时的试用,终于找到了解决方案。下面的解决方案是使用Apollo Client v0.41.0和Swift 5进行测试的

  1. import Foundation
  2. import Apollo
  3. class Network {
  4. static let shared = Network()
  5. private(set) lazy var apollo: ApolloClient = {
  6. let cache = InMemoryNormalizedCache()
  7. let store1 = ApolloStore(cache: cache)
  8. let authPayloads = ["Authorization": "Bearer <<TOKEN>>"]
  9. let configuration = URLSessionConfiguration.default
  10. configuration.httpAdditionalHeaders = authPayloads
  11. let client1 = URLSessionClient(sessionConfiguration: configuration, callbackQueue: nil)
  12. let provider = NetworkInterceptorProvider(client: client1, shouldInvalidateClientOnDeinit: true, store: store1)
  13. let url = URL(string: "https://<HOST NAME>/graphql")!
  14. let requestChainTransport = RequestChainNetworkTransport(interceptorProvider: provider,
  15. endpointURL: url)
  16. return ApolloClient(networkTransport: requestChainTransport,
  17. store: store1)
  18. }()
  19. }
  20. class NetworkInterceptorProvider: DefaultInterceptorProvider {
  21. override func interceptors<Operation: GraphQLOperation>(for operation: Operation) -> [ApolloInterceptor] {
  22. var interceptors = super.interceptors(for: operation)
  23. interceptors.insert(CustomInterceptor(), at: 0)
  24. return interceptors
  25. }
  26. }
  27. class CustomInterceptor: ApolloInterceptor {
  28. func interceptAsync<Operation: GraphQLOperation>(
  29. chain: RequestChain,
  30. request: HTTPRequest<Operation>,
  31. response: HTTPResponse<Operation>?,
  32. completion: @escaping (Swift.Result<GraphQLResult<Operation.Data>, Error>) -> Void) {
  33. request.addHeader(name: "Authorization", value: "Bearer <<TOKEN>>")
  34. print("request :\(request)")
  35. print("response :\(String(describing: response))")
  36. chain.proceedAsync(request: request,
  37. response: response,
  38. completion: completion)
  39. }
  40. }

字符串

展开查看全部
mm9b1k5b

mm9b1k5b2#

从Apollo Client v0.34.0及以上版本开始,之前提供的代码将无法工作,因为他们重写了它以前的工作方式。以下是对我有效的代码.有关更多信息,请参阅此处链接中的文档。

  1. class Network {
  2. static let shared = Network()
  3. private(set) lazy var apollo: ApolloClient = {
  4. let client = URLSessionClient()
  5. let cache = InMemoryNormalizedCache()
  6. let store = ApolloStore(cache: cache)
  7. let provider = NetworkInterceptorProvider(client: client, store: store)
  8. let url = URL(string: "https://www.graphqlapi.com/")!
  9. let transport = RequestChainNetworkTransport(interceptorProvider: provider,
  10. endpointURL: url)
  11. return ApolloClient(networkTransport: transport)
  12. }()
  13. }
  14. class NetworkInterceptorProvider: LegacyInterceptorProvider {
  15. override func interceptors<Operation: GraphQLOperation>(for operation: Operation) -> [ApolloInterceptor] {
  16. var interceptors = super.interceptors(for: operation)
  17. interceptors.insert(CustomInterceptor(), at: 0)
  18. return interceptors
  19. }
  20. }
  21. class CustomInterceptor: ApolloInterceptor {
  22. // Find a better way to store your token this is just an example
  23. let token = "YOUR TOKEN"
  24. func interceptAsync<Operation: GraphQLOperation>(
  25. chain: RequestChain,
  26. request: HTTPRequest<Operation>,
  27. response: HTTPResponse<Operation>?,
  28. completion: @escaping (Result<GraphQLResult<Operation.Data>, Error>) -> Void) {
  29. request.addHeader(name: "authorization", value: "Bearer: \(token)")
  30. chain.proceedAsync(request: request,
  31. response: response,
  32. completion: completion)
  33. }
  34. }

字符串

展开查看全部
fjaof16o

fjaof16o3#

最后我找到了答案。按以下方式添加标题,

  1. let apolloAuth: ApolloClient = {
  2. let configuration = URLSessionConfiguration.default
  3. let token = UserDefaults.standard.value(forKey: "token")
  4. // Add additional headers as needed
  5. configuration.httpAdditionalHeaders = ["authorization":"\(token!)", "channel":"mobile"]
  6. let url = URL(string: "http://xxxx/graphql")!
  7. return ApolloClient(networkTransport: HTTPNetworkTransport(url: url, configuration: configuration))
  8. }()

字符串
希望它能帮助某人。

6jygbczu

6jygbczu4#

接受的解决方案现在已经过时,因为HTTPNetworkTransport不再接受配置参数,而是直接接受URLSession而不是URLSessionConfiguration
下面是一个示例,如何在每个请求上向Apollo客户端发送授权头,如果找到,则从Apollo客户端(iOS)的version 0.21.0中的Username中检索它。

  1. import Foundation
  2. import Apollo
  3. class Network {
  4. static let shared = Network()
  5. private(set) lazy var apollo: ApolloClient = {
  6. let token = UserDefaults.standard.string(forKey: "accessToken") ?? ""
  7. let url = URL(string: "http://localhost:4000/graphql")!
  8. let configuration = URLSessionConfiguration.default
  9. configuration.httpAdditionalHeaders = ["authorization": "Bearer \(token)"]
  10. return ApolloClient(
  11. networkTransport: HTTPNetworkTransport(url: url, session: URLSession(configuration: configuration))
  12. )
  13. }()
  14. }

字符串

展开查看全部
zbsbpyhn

zbsbpyhn5#

更新:Apollo Client v0.34.0后不推荐使用此解决方案

以前的答案是旧的,现在通过委托完成:
该协议允许对请求进行飞行前验证,能够在修改请求之前进行保释,并能够使用附加标头等内容修改URLRequest。

  1. import Foundation
  2. import Apollo
  3. final class Network {
  4. static let shared = Network()
  5. private lazy var networkTransport: HTTPNetworkTransport = {
  6. let transport = HTTPNetworkTransport(url: URL(string: "https://example.com/graphql")!)
  7. transport.delegate = self
  8. return transport
  9. }()
  10. private(set) lazy var apollo = ApolloClient(networkTransport: self.networkTransport)
  11. }
  12. extension Network: HTTPNetworkTransportPreflightDelegate {
  13. func networkTransport(_ networkTransport: HTTPNetworkTransport, shouldSend request: URLRequest) -> Bool {
  14. return true
  15. }
  16. func networkTransport(_ networkTransport: HTTPNetworkTransport, willSend request: inout URLRequest) {
  17. var headers = request.allHTTPHeaderFields ?? [String: String]()
  18. headers["Authorization"] = "Bearer \(YOUR_TOKEN)"
  19. request.allHTTPHeaderFields = headers
  20. }
  21. }

字符串
这里有一个链接到文档的更多细节:
https://www.apollographql.com/docs/ios/initialization/

展开查看全部
bqujaahr

bqujaahr6#

导入这两个元素

  1. import UIKit
  2. import Apollo

字符串
创建一个类Network并粘贴到下面的源代码

  1. struct Network {
  2. static var request = Network()
  3. private(set) lazy var apollo: ApolloClient = {
  4. let cache = InMemoryNormalizedCache()
  5. let store1 = ApolloStore(cache: cache)
  6. let authPayloads = ["Authorization": "Bearer <TOKEN>"]
  7. let configuration = URLSessionConfiguration.default
  8. configuration.httpAdditionalHeaders = authPayloads
  9. let client1 = URLSessionClient(sessionConfiguration: configuration, callbackQueue: nil)
  10. let provider = NetworkInterceptorProvider(client: client1, shouldInvalidateClientOnDeinit: true, store: store1)
  11. let url = URL(string: "http://xxx/graphql")!
  12. let requestChainTransport = RequestChainNetworkTransport(interceptorProvider: provider,
  13. endpointURL: url)
  14. return ApolloClient(networkTransport: requestChainTransport,
  15. store: store1)
  16. }()
  17. }


在Network类中添加NetworkInterceptorProvider

  1. class NetworkInterceptorProvider: LegacyInterceptorProvider {
  2. override func interceptors<Operation: GraphQLOperation>(for operation: Operation) -> [ApolloInterceptor] {
  3. var interceptors = super.interceptors(for: operation)
  4. interceptors.insert(CustomInterceptor(), at: 0)
  5. return interceptors
  6. }


}
在Network类中也添加CustomInterceptor

  1. class CustomInterceptor: ApolloInterceptor {
  2. func interceptAsync<Operation: GraphQLOperation>(
  3. chain: RequestChain,
  4. request: HTTPRequest<Operation>,
  5. response: HTTPResponse<Operation>?,
  6. completion: @escaping (Swift.Result<GraphQLResult<Operation.Data>, Error>) -> Void) {
  7. request.addHeader(name: "Authorization", value: "Bearer <TOKEN>")
  8. print("request :\(request)")
  9. print("response :\(String(describing: response))")
  10. chain.proceedAsync(request: request,
  11. response: response,
  12. completion: completion)
  13. }


}
finally从ViewController调用此方法

  1. func todoQueryCloud(){
  2. Network.request.apollo.fetch(query: ProgressionsQuery()){result in
  3. // 3
  4. switch result {
  5. case .success(let graphQLResult):
  6. guard let data = try? result.get().data else { return }
  7. if graphQLResult.data != nil {
  8. // 4
  9. print("Loaded data \(String(describing: data.progressions))")
  10. self.collectionView.reloadData()
  11. }
  12. case .failure(let error):
  13. // 5
  14. print("Error loading data \(error)")
  15. }
  16. }
  17. }

展开查看全部
fjaof16o

fjaof16o7#

NetworkInterceptorProvider:LegacyInterceptorProvider更改为“DefaultInterceptorProvider”

  1. class NetworkInterceptorProvider: DefaultInterceptorProvider {
  2. override func interceptors<Operation: GraphQLOperation>(for operation: Operation) -> [ApolloInterceptor] {
  3. var interceptors = super.interceptors(for: operation)
  4. interceptors.insert(CustomInterceptor(), at: 0)
  5. return interceptors
  6. }

字符串
}

q9rjltbz

q9rjltbz8#

更新了Apollo 1.6.1的解决方案

  1. import Foundation
  2. import Apollo
  3. class DataCoordinator: NSObject {
  4. // MARK: Variables
  5. static let shared: DataCoordinator = DataCoordinator()
  6. private(set) lazy var apolloClient: ApolloClient = {
  7. let cache = InMemoryNormalizedCache()
  8. let store = ApolloStore(cache: cache)
  9. let authPayloads = ["Authorization": "Bearer \(token)"]
  10. let configuration = URLSessionConfiguration.default
  11. configuration.httpAdditionalHeaders = authPayloads
  12. let client = URLSessionClient(sessionConfiguration: configuration, callbackQueue: nil)
  13. let provider = NetworkInterceptorProvider(store: store, client: client)
  14. let url = URL(string: "https://xxxxxxxxx/graphql")!
  15. let requestChainTransport = RequestChainNetworkTransport(interceptorProvider: provider, endpointURL: url)
  16. return ApolloClient(networkTransport: requestChainTransport, store: store)
  17. }()
  18. }
  19. struct NetworkInterceptorProvider: InterceptorProvider {
  20. // These properties will remain the same throughout the life of the `InterceptorProvider`, even though they
  21. // will be handed to different interceptors.
  22. private let store: ApolloStore
  23. private let client: URLSessionClient
  24. init(store: ApolloStore,
  25. client: URLSessionClient) {
  26. self.store = store
  27. self.client = client
  28. }
  29. func interceptors<Operation>(for operation: Operation) -> [ApolloInterceptor] {
  30. return [
  31. MaxRetryInterceptor(),
  32. CacheReadInterceptor(store: self.store),
  33. NetworkFetchInterceptor(client: self.client),
  34. ResponseCodeInterceptor(),
  35. JSONResponseParsingInterceptor(),
  36. AutomaticPersistedQueryInterceptor(),
  37. CacheWriteInterceptor(store: self.store)
  38. ]
  39. }
  40. }

字符串
快乐编程

展开查看全部
xtupzzrd

xtupzzrd9#

我一直在学习https://www.apollographql.com/docs/ios/tutorial/tutorial-execute-first-query的教程
如果你的目标只是添加一个自定义头,那么最简单的方法就是

  1. import Apollo
  2. import Foundation
  3. class Network {
  4. static let shared = Network()
  5. private(set) lazy var apollo: ApolloClient = {
  6. let url = URL(string: "https://example.com/v1/graphql")!
  7. let configuration = URLSessionConfiguration.default
  8. configuration.httpAdditionalHeaders = ["Authorization": "Bearer token"] // Add your headers here
  9. let client = URLSessionClient(sessionConfiguration: configuration)
  10. let store = ApolloStore(cache: InMemoryNormalizedCache())
  11. let provider = DefaultInterceptorProvider(client: client, store: store)
  12. let networkTransport = RequestChainNetworkTransport(interceptorProvider: provider, endpointURL: url)
  13. return ApolloClient(networkTransport: networkTransport, store: store)
  14. }()
  15. }

字符串
希望能对大家有所帮助!

展开查看全部

相关问题