Как правильно использовать Apollo GraphQL на iOS с настройкой фоновой сессии? - PullRequest
0 голосов
/ 29 апреля 2018

Я использую 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 Ответ

0 голосов
/ 04 мая 2018

Apollo iOS предоставляет общедоступный протокол NetworkTransport, который позволяет переопределять все сетевые взаимодействия. Реализация может быть предоставлена ​​в качестве аргумента ApolloClient(networkTransport: NetworkTransport) initializer.

Предположим, у вас есть реализация 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 в фоновом режиме и некоторыми другими функциями. .

...