Как правильно использовать Apollo GraphQL на iOS с настройкой фоновой сессии?
Я использую 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 в фоновом режиме?
1 ответ
Apollo iOS предоставляет общественности 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 в своем приложении, вы также можете использовать библиотеку ApolloAlamofire, которая обеспечивает реализацию NetworkTransport
с поддержкой фона URLSession
конфигурация и еще несколько функций.