CloudKit 不检索应该存在且可检索的记录

Posted

技术标签:

【中文标题】CloudKit 不检索应该存在且可检索的记录【英文标题】:CloudKit does not retrieve record that should be there and retrievable 【发布时间】:2018-07-17 01:12:40 【问题描述】:

我有一个在 CloudKit 中创建新记录的函数。成功创建该记录后,它会调用一个名为 refresh() 的函数,该函数将调用其他一些查询我刚刚创建的记录的函数。但是,它说我创建了记录,但它从来没有进入下一个查询,这告诉我新记录在被查询之前可能没有及时到达 CloudKit。顺便说一句,如果我要查看数据库,记录是正确创建的。

创建新记录功能:

func saveCreatedGroup2()
    let Group = CKRecord(recordType: "Group")
    print(groupName)
    Group.setObject(groupName as CKRecordValue?, forKey: "groupName")
    Group.setObject(groupDesc as CKRecordValue?, forKey: "groupDesc")
    Group.setObject(publicOrPrivate as CKRecordValue?, forKey: "PublicOrPrivate")
    Group.setObject(members as CKRecordValue?, forKey: "memberUsernames")
    Group.setObject(leaders as CKRecordValue?, forKey: "leaders")

    database.save(Group)  (savedRecord, error) in
        if error != nil
            print(error.debugDescription)
        else
            DispatchQueue.main.async
            print("SAVED RECORD, CREATED NEW GROUP!!!!")
            // IT DOES SAY THIS^
            thisTeamName = selectedCellName
            createdNewGroup = false
            self.refresh()
            
        

    


刷新()函数:

func refresh()
    tempThisGroupTuple = []
    sortedTupleArray = []
    otherTeam = []
    otherSortedArray = []
    tempOtherTeamTuple = []
    canSwitchViews = false
    if (canRefresh == false)
    print ("ABANDONED")
    refreshControl.endRefreshing()

    else
    loadGroupPage()
    DispatchQueue.main.async
    self.requestsTableView.reloadData()
    self.groupFeedTableView.reloadData()
    
    

loadGroupPage()(查询刚刚创建的记录)函数 - 打印查询之前的行,但不打印查询内部的行!:

func loadGroupPage() 
    print("loadingf group pagew...\(thisTeamName)") // PRINTS THIS

    let pred = NSPredicate(format: "groupName = %@", thisTeamName)
    let query = CKQuery(recordType: "Group", predicate: pred)
    let operation = CKQueryOperation(query: query)
    operation.qualityOfService = .userInteractive
    var canJoin = false
    var requestVisible = false
    operation.recordFetchedBlock =  (record: CKRecord!) in

        if record != nil

            self.OurGroup = record

            groupMembs = (record.object(forKey: "memberUsernames") as! Array) // loads group members
            print("original groupMembs: \(groupMembs)") // DOES NOT PRINT THIS LINE, SO IT IS TELLING ME IT DID NOT FIND THE RECORD

            ...(There's more to this function but it's unnecessary)

我还确认,当查询开始时,谓词/“thisTeamName”应该是它的样子,也就是刚刚创建的记录的组名。我对为什么它无法检索/查询记录感到困惑。

【问题讨论】:

同样的问题。复制。 ***.com/questions/42729601/… 为什么要先存储记录,然后在同一个应用程序中立即检索记录?不是 Cloudkit 用于传输,还有 CoreData/Realm/simple structs/etc。用于本地缓存/存储?我的意思是这样做的目的是什么?不必维护本地存储?用“在线优先”简化代码? 【参考方案1】:

您的刷新函数调用 loadGroupPage(),然后立即触发异步调用以重新加载表,而无需等待 loadGroupPage 函数完成,因此即使您确实获得了记录,我认为它不会正常工作。

您不会在 loadGroupPage 函数中显示实际将请求操作添加到数据库的位置。我假设它在那里?

recordFetchedBlock 将为返回的每条记录触发一次,您无需强制解开记录(记录:CKRecord!)。您也不需要检查记录!= nil,因为它保证在那里。

CKQuery recordFetchedBlock 文档说:

警告

查询索引是异步更新的,因此不能保证它们是最新的。如果您查询最近更改的记录并且没有足够的时间来处理这些更改,则查询结果可能不正确。结果可能不包含正确的记录,并且记录可能有问题。

无论如何我都不是专家(也没有使用过便利的 API),但我的应用程序内置了同步功能,根据我的经验,如果问题是索引没有更新,我会感到惊讶。

我建议添加一个 queryCompletionBlock 并在那里检查错误。在使用 CloudKit 时,您应该始终检查错误,因为即使代码正确,仍然会出现错误(网络不可用、iCloud 关闭等)

【讨论】:

1) 重新加载表应该无关紧要,因为查询中的打印行没有被调用。 2)是的,最后。 3) 不必要的 4) 可能是问题 5) 我已经有一个完成块来检查错误。呜呜呜…… 所以你没有得到任何错误,没有记录回来但是当你检查它时记录存在。你试过只查询我猜的所有存在的记录吗?那也没有回报?以及在创建记录后不立即进行查询怎么办。我仍然怀疑这是一个索引问题 - 事情似乎在我完成后立即返回(尽管我没有使用便捷 API) 我只是在解决它。仍然有这个问题,但不是很在意它。谢谢你的帮助 这可能适用于您的情况。 ***.com/questions/34824301/…

以上是关于CloudKit 不检索应该存在且可检索的记录的主要内容,如果未能解决你的问题,请参考以下文章

用于从 cloudkit 检索单列的代码模式/片段

使用 CloudKit 和 Swift 检索图像

如何在 CloudKit 中存储和检索音频文件?

如何使用objective-c从CloudKit中的资产字段中检索图像

从 CloudKit 检索新数据后更新 tableView 数据

CloudKit - 无法从 iCloud 检索数据