表不会加载/显示 CloudKit 数据

Posted

技术标签:

【中文标题】表不会加载/显示 CloudKit 数据【英文标题】:Table Will Not Load/Show CloudKit Data 【发布时间】:2017-11-12 22:01:15 【问题描述】:

我正在使用 CloudKit 来存储一些数组,然后使用这些数组来填充表格。我正在重新加载表格,但它不会显示任何数据。它应该连接到 iCloud,因为我仍然可以添加到数据库。

代码如下:

import UIKit
import CloudKit

var selectedCellName = ""

class explore: UIViewController, UITableViewDataSource, UITableViewDelegate 
    @IBOutlet var tableView: UITableView!

    var groupNames = [String]()
    var Group = [CKRecord]()

    override func viewDidLoad() 
        super.viewDidLoad()

        loadGroups()
        self.tableView.reloadData()
    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return groupNames.count
    

    func numberOfSections(in tableView: UITableView) -> Int 
        return 1
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = self.tableView.dequeueReusableCell(withIdentifier: "exploreCell")! as UITableViewCell
        // let nameCell = leaderboardInfo[indexPath.row].object(forKey: "Name") as! String
        // let usernameCell = leaderboardInfo[indexPath.row].object(forKey: "Username") as! String
        //let pointsCell = leaderboardInfo[indexPath.row].object(forKey: "Points") as! String
        var nameCellLbl = cell.viewWithTag(100) as! UILabel

        nameCellLbl.text = groupNames[indexPath.row]

        return cell
    

这是用于查询数据库的loadGroups()函数:

 func loadGroups()
    print("should go")
    // let pred = NSPredicate(format: "Username = %@", usernameText)
    let pred = NSPredicate(value: true)
    let query = CKQuery(recordType: "Group", predicate: pred)
    let operation = CKQueryOperation(query: query)
    //operation.resultsLimit = CKQueryOperationMaximumResults
    operation.qualityOfService = .default
    operation.recordFetchedBlock =  (record: CKRecord!) in

        if record != nil

            // need self in front?
            groupNames.append(record.object(forKey: "groupName") as! String)


            //self.tableView.reloadData()
            //print(self.groupNames.count)

        


      
    database.add(operation)
    //self.tableView.reloadData()
    // print(leaderboardInfo.count)

这曾经有效,如果我做了更改,我几个月前就做了,所以我不记得了。无论如何,这是我查询数据库的所有文件中的问题,但表不会加载它。

【问题讨论】:

【参考方案1】:

您在实际查询数据之前很久就重新加载了表视图。

删除viewDidLoad中对reloadData的调用。

loadGroups 中,您需要设置一个查询完成处理程序。您需要处理查询完成处理程序指示有更多数据要加载的可能性。

您应该从查询的数据中构建一个新数组。在获得所有数据之前不要更新groupNames。然后,在主队列上,使用查询结果更新groupNames,然后重新加载表格视图。

更好的解决方案是将完成处理程序添加到您的 loadGroups 方法中。然后不是loadGroups 直接更新groupNames 并重新加载表视图,而是简单地传回一个包含所有查询数据的新数组。然后调用者可以更新groupNames 并重新加载表视图,完成块传递给loadGroups 的调用。

func loadGroups(completion: ((_ groups: [String]) -> Void)) 
    var names = [String]()

    // setup operation
    ...
    operation.recordFetchedBlock =  (record: CKRecord!) in
        if record != nil 
            names.append(record.object(forKey: "groupName") as! String)
        
    

    operation.queryCompletionBlock =  (cursor, error) in 
        // properly handle cursor and error

        completion(names)
    

然后可以从您的视图控制器中调用它:

loadGroups()  (names) in
    DispatchQueue.main.async 
        groupNames = names
        tableView.reloadData()
    

以上是粗略的概述。这并不意味着可以投入生产。

【讨论】:

我添加了一个简单的刷新按钮,它只是重新加载表格。我相信它应该可以工作,但它没有,即使我等了一分钟 问题可能是 groupNames 是空的...你在 loadGroups() 函数中看到我说 append 语句前面可能有一个 self 吗?当函数在不同的文件中时如何添加? 查看我的更新答案以获得更好的解决方案,即使loadGroups 属于不同的班级。 我喜欢这个新想法。除了我之前没有使用过完成处理程序,你介意写我需要的那一行,然后我可以把剩下的代码放在自己里面吗?

以上是关于表不会加载/显示 CloudKit 数据的主要内容,如果未能解决你的问题,请参考以下文章

注释不会在地图上加载

在 CloudKit 中处理多对多关系

CloudKit 应用程序数据未显示在表格视图中

Cloudkit + 核心数据不同步

表数据不会动态重新加载

SwiftUI 和 CloudKit 异步数据加载