1

我正在使用 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,我都会收到错误Generic parameter 'Query' could not be inferred。

但是,当注释掉该行时,它可以正常工作,但显然该功能毫无意义。最终我想概括这个函数,以便我可以将查询传递给它,但是我如何从这个基本闭包中获取数据?

本质上,问题是,我如何在函数中“包装”闭包?

这个函数的重点是能够在函数中获取表格视图部分的行数:

override func tableView(_ tableView:UITableView, numberOfRowsInSection section: Int -> Int{
    return fetchQueryResults.count
}

但是,视图会在此函数运行之前加载。我认为这是因为apollo.fetch()异步运行?

4

2 回答 2

2

目前我正在使用 Apollo iOS 版本 0.16.0,这是最新版本 https://github.com/apollographql/apollo-ios

有一些与低于 0.13.0 的版本相关的更改,您可以查看0.13.0 发行说明- 不要使用(result, error),因为它们已从可为空参数的元组切换到结果。

尝试使用这样的东西:

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)
        }

    }
于 2019-09-27T21:59:57.450 回答
1

每当我添加行 myResult = result?.data 时,我都会收到错误 Generic parameter 'Query' could not be inferred。

有几件事可能会解决它:

  1. 添加import Apollo到该 Swift 文件中。您可能已经拥有它,但如果您apollo使用静态实用程序类创建实例,那是可能的。

  2. 把它, error放在你的关闭中,所以它只是{ result in. 我认为这是许多教程中的较旧语法,但error现在是其result本身的一部分。

但是,视图会在此函数运行之前加载。我认为这是因为 apollo.fetch() 是异步运行的?

默认情况下,它运行DispatchQueue.main,但您可以使用fetch()函数调用并填写您希望它在哪个 DispatchQueue 上运行(即,当您在 xCode 中键入“fetch”时,自动完成实际上会将其显示为 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
}
于 2019-08-08T00:51:04.503 回答