如何通过后台会话配置在 iOS 上正确使用 Apollo GraphQL?
How to correctly use Apollo GraphQL on iOS with background session configuration?
我将 Apollo iOS 0.8 与 Xcode 9.3、Swift 4.1 和 iOS 11 一起使用,并像这样初始化 Apollo 客户端实例:
import Apollo
// ... unrelated code skipped
let configuration = URLSessionConfiguration.default
if let token = keychain.accessToken {
// Add additional headers as needed
configuration.httpAdditionalHeaders = [
"Authorization": "Bearer \(token)"
]
}
let graphqlEndpoint = URL("https://sample-server-url/graphql")!
let client = ApolloClient(networkTransport:
HTTPNetworkTransport(url: graphqlEndpoint, configuration: configuration))
该应用程序可以很好地处理发送到 GraphQL 服务器的所有查询和变更,除非该应用程序在后台运行。据我所知,对于常见的 NSURLSession
实例,可以通过将会话配置切换为 URLSessionConfiguration.background(withIdentifier: "your-session-id")
.
轻松解决
但是当我更换线时
let configuration = URLSessionConfiguration.default
和
let configuration = URLSessionConfiguration.background(withIdentifier: "your-session-id")
应用程序开始崩溃并出现此错误:Terminating app due to uncaught exception 'NSGenericException', reason: 'Completion handler blocks are not supported in background sessions. Use a delegate instead.'
使用 Apollo GraphQL 时解决此错误的最佳方法是什么,或者是否有任何其他方法可以在后台与 GraphQL 服务器通信?
Apollo iOS 提供了一个 public NetworkTransport
协议,允许覆盖所有网络交互。可以将实现作为 ApolloClient(networkTransport: NetworkTransport)
初始化器的参数提供。
假设您有一个 NetworkTransport
实现,它使用后台会话配置包装 URLSession
实现:
class BackgroundTransport: NetworkTransport {
public func send<Operation>(operation: Operation,
completionHandler: @escaping (GraphQLResponse<Operation>?, Error?) -> Void)
-> Cancellable where Operation: GraphQLOperation {
// ...
}
}
然后你可以这样初始化ApolloClient
:
let graphqlEndpoint = URL("https://sample-server-url/graphql")!
let client = ApolloClient(networkTransport: BackgroundTransport(url: u))
BackgroundTransport
实现可以根据需要自定义,包括根据后台会话配置的需要使用 URLSession
委托而不是完成处理程序块。
如果您使用 Alamofire in your app, you can also use ApolloAlamofire 库,该库提供 NetworkTransport
的实现,支持后台 URLSession
配置和更多功能。
我将 Apollo iOS 0.8 与 Xcode 9.3、Swift 4.1 和 iOS 11 一起使用,并像这样初始化 Apollo 客户端实例:
import Apollo
// ... unrelated code skipped
let configuration = URLSessionConfiguration.default
if let token = keychain.accessToken {
// Add additional headers as needed
configuration.httpAdditionalHeaders = [
"Authorization": "Bearer \(token)"
]
}
let graphqlEndpoint = URL("https://sample-server-url/graphql")!
let client = ApolloClient(networkTransport:
HTTPNetworkTransport(url: graphqlEndpoint, configuration: configuration))
该应用程序可以很好地处理发送到 GraphQL 服务器的所有查询和变更,除非该应用程序在后台运行。据我所知,对于常见的 NSURLSession
实例,可以通过将会话配置切换为 URLSessionConfiguration.background(withIdentifier: "your-session-id")
.
但是当我更换线时
let configuration = URLSessionConfiguration.default
和
let configuration = URLSessionConfiguration.background(withIdentifier: "your-session-id")
应用程序开始崩溃并出现此错误:Terminating app due to uncaught exception 'NSGenericException', reason: 'Completion handler blocks are not supported in background sessions. Use a delegate instead.'
使用 Apollo GraphQL 时解决此错误的最佳方法是什么,或者是否有任何其他方法可以在后台与 GraphQL 服务器通信?
Apollo iOS 提供了一个 public NetworkTransport
协议,允许覆盖所有网络交互。可以将实现作为 ApolloClient(networkTransport: NetworkTransport)
初始化器的参数提供。
假设您有一个 NetworkTransport
实现,它使用后台会话配置包装 URLSession
实现:
class BackgroundTransport: NetworkTransport {
public func send<Operation>(operation: Operation,
completionHandler: @escaping (GraphQLResponse<Operation>?, Error?) -> Void)
-> Cancellable where Operation: GraphQLOperation {
// ...
}
}
然后你可以这样初始化ApolloClient
:
let graphqlEndpoint = URL("https://sample-server-url/graphql")!
let client = ApolloClient(networkTransport: BackgroundTransport(url: u))
BackgroundTransport
实现可以根据需要自定义,包括根据后台会话配置的需要使用 URLSession
委托而不是完成处理程序块。
如果您使用 Alamofire in your app, you can also use ApolloAlamofire 库,该库提供 NetworkTransport
的实现,支持后台 URLSession
配置和更多功能。