我正在使用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
时,都无法推断出错误通用参数'QUERY'。
但是,当线条评论时,效果很好,但显然该功能毫无意义。最终,我想概括此功能,以便可以将查询传递到其中,但是如何将数据从此基本关闭中获取?
本质上的问题是,我如何"包裹"函数中的封闭?
此功能的重点是能够在功能中获得表视图部分的行数:
override func tableView(_ tableView:UITableView, numberOfRowsInSection section: Int -> Int{
return fetchQueryResults.count
}
但是,在此功能运行之前,视图加载。我认为这是因为 apollo.fetch()
异步运行?
当前我正在使用Apollo iOS版本0.16.0,这是最新版本https://github.com/apollographql/apollo-ios
有一些与低于0.13.0的版本有关的更改,您可以查看0.13.0发行说明 - 不要使用(result, error)
,因为它们已从可无效的参数切换到结果。<<<<<<<<<<<</p>
尝试使用这样的东西:
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)
}
}
每当我添加line myResult = result = result?.data时,我都无法推断出错误的通用参数'query'。
几件事可以修复它:
-
将
import Apollo
添加到该快速文件中。您可能已经拥有它了,但是如果您使用静态实用程序类创建apollo
实例,则可能是可能的。 -
将
, error
放在您的关闭中,因此仅是{ result in
。我认为这是较旧的语法,其中有很多教程,但是error
现在已成为result
本身的一部分。
但是,在此功能运行之前,视图加载。我认为这是因为apollo.fetch()正在异步运行?
默认情况下,它运行DispatchQueue.main
,但是您可以使用fetch()
函数调用并填写要运行的discatchqueue(即,在Xcode中键入" fetch"时,AutoComplete实际上将显示为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
}