Я использую Apollo iOS для получения запросов GraphQL. Я хочу переместить закрытие запросов apollo.fetch() в отдельную функцию в классе. Этот класс будет содержать статическую ссылку на клиент apollo, а также функции для выполнения мутаций и запросов GraphQL.
Я пытаюсь сделать следующее:
static func fetchQueryResults() -> CountriesQuery.Data.Country?{
var myResult: CountriesQuery.Data.Country?
myResult = nil
apollo.fetch(query: countriesQuery) { (result, error) in
print(result?.data)
myResult = result?.data //this line causes error
}
return myResult
}
Всякий раз, когда я добавляю строку myResult = result?.data, я получаю сообщение об ошибке Общий параметр "Запрос" не может быть выведен.
Однако, когда строка закомментирована, она работает нормально, но очевидно, что функция бессмысленна. В конце концов я хотел бы обобщить эту функцию, чтобы я мог передавать в нее запрос, но как мне получить данные из этого базового замыкания?
По сути вопрос, как мне «обернуть» закрытие в функцию?
Смысл этой функции в том, чтобы иметь возможность получить количество строк для раздела табличного представления в функции:
override func tableView(_ tableView:UITableView, numberOfRowsInSection section: Int -> Int{
return fetchQueryResults.count
}
Однако представление загружается до запуска этой функции. Я думаю, это потому, что apollo.fetch() работает асинхронно?
@Naresh опечатка в посте, только что исправил
не уверен насчет этой ошибки, но я бы посоветовал вам не использовать функцию в качестве источника данных... сохранить массив... Я знаю, в чем ваша путаница, ингредиент, который вам не хватает, называется экранирующим замыканием... иди сюда чтобы понять это - medium.com/@bestiosdevelope/… потребуется некоторое время, чтобы понять это, зависит от вашего опыта... после того, как вы реализуете закрытие, ваш fetchQueryResults ничего не вернет, но предоставит массив в качестве входных данных для закрытия, которое обновит представление таблицы так далее...





Whenever I add the line myResult = result?.data I get the error Generic parameter 'Query' could not be inferred.
Пара вещей, которые мощь исправляет:
Добавьте import Apollo к этому файлу Swift. Вероятно, он у вас уже есть, но если вы создадите свой экземпляр apollo, используя статический служебный класс, это возможно.
Отбросьте , error в конце, чтобы это было просто { result in. Я думаю, что это старый синтаксис, который используется во многих учебниках, но error теперь является частью самого result.
However, the view loads before this function runs. I think this is because the apollo.fetch() is running asynchronously?
По умолчанию он запускается DispatchQueue.main, но вы можете использовать вызов функции fetch() и указать, в какой очереди DispatchQueue вы хотите, чтобы он работал (например, когда вы вводите «fetch» в xCode, автозаполнение фактически покажет его как 2 разные сигнатуры func: одна, которая скрывает все параметры со значениями по умолчанию, и второй, где вы можете явно заполнить каждый параметр).
В общем, хороший шаблон для асинхронной загрузки данных в виде таблицы:
var countries: [Country] = [Country]()
func viewDidLoad() {
super.viewDidLoad()
apollo.fetch(query: countriesQuery) { result in
self.countries.removeAll() // clear the old data
// unpack each Country from result
// add to countries array
self.tableView.reloadData() // tell the table view to refresh
}
}
override func tableView(_ tableView:UITableView, numberOfRowsInSection section: Int -> Int{
return countries.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let country = countries[indexPath.row]
let yourCell: YourCell = tableView.dequeueReusableCell(withIdentifier: "yourCellKey", for: indexPath) as! YourCell
yourCell.setCountry(country)
return yourCell
}
В настоящее время я использую Apollo iOS версии 0.16.0, которая является последней версией. https://github.com/apollographql/apollo-ios
Есть несколько изменений, связанных с версией ниже 0.13.0, вы можете взглянуть на Примечания к выпуску 0.13.0 — не используйте (result, error), потому что они переключились с кортежа параметров, допускающих значение NULL, на результат.
Попробуйте использовать что-то вроде этого:
Apollo.shared.client.fetch(query: GetProductQuery(id: id)) { results in
do {
if let gqlErrors = try results.get().errors {
if (!gqlErrors.isEmpty) {
apiResponseError.message = gqlErrors[0].message
publishSubject.onError(apiResponseError)
}
return
}
guard let gplResult = try results.get().data?.getProduct else {
apiResponseError.message = "Error getting results"
publishSubject.onError(apiResponseError)
return
}
publishSubject.onNext(gplResult)
} catch let errorException {
apiResponseError.message = errorException.localizedDescription
publishSubject.onError(apiResponseError)
}
}
Я запутался... ваше закрытие принимает "результат" в качестве параметра, и вы используете "результаты"