iOS上的CloudKit无法获取所有我想要的记录

时间:2018-03-17 23:59:18

标签: ios swift cloudkit

我使用CloudKit为我的应用程序获取记录的api不再正常工作。它只在一两周前开始这样做。它从公共数据库中获取,而不是私有数据库。

例如,我有一个名为“Part”的记录类型,其中包含一些值,包括“datestamp”字段。应用程序第一次启动时,它应该使用CKQueryOperation获取私有数据库中Part(和其他)的所有记录,然后在后续启动时,它使用CKFetchRecordZoneChangesOperation获取任何新记录。在我的个人iCloud帐户中,我有超过1,000条这些记录。但是查询操作和获取更改操作只能获取完全相同的 107 记录而不能再获取。这不是resultLimits的问题,我已经实现了对CKQueryCursor的检查。作为一个实验,我给它一个谓词来仅获取日期戳为2018年1月或之后的记录 - 它返回 0 记录。还有另一种记录类型在我的数据库中有12条记录,但只有 1 正在同步。

我将同步类设计为跨平台API。它适用于我的iOS,macOS和tvOS目标。 macOS目标同步很好 ,即使它使用完全相同的代码行。 iOS和tvOS已经运行了近2年。除了现在在NSOperation子类中使用类之外,几乎没有任何改变。我尝试过多款iPhone,iPad,iOS模拟器实例,iOS版本,Xcode版本。我尝试过不同的iCloud帐户。我不知道问题是什么。但是这个错误阻碍了我发布一个急需的更新。我想也许这只是Apple在开发环境中的一个错误,并且在公开发布时会很好用,但我害怕禁用所有用户。

 protocol CloudData {
    var privateDatabase : CKDatabase { get }
 }

 extension CloudData {
    var privateDatabase : CKDatabase {
       return CKContainer (identifier: "iCloud...").privateDatabase
    }
 }

 final class CloudSync : CloudData {

    func initialSync {

         ...

         // Create an operation to fetch all PARTS
        let partQuery = CKQuery (recordType: "Part", predicate: NSPredicate(value: true))
        let partOperation = CKQueryOperation (query: partQuery)
        partOperation.recordFetchedBlock = { partRecords += [$0] }
        partOperation.zoneID = zoneID
        partOperation.queryCompletionBlock = { cursor, error in

            if let cursorObj = cursor {

                print("Initial Sync - Cursor Found Parts")

                let newOp = CKQueryOperation (cursor: cursorObj)
                newOp.recordFetchedBlock = partOperation.recordFetchedBlock
                newOp.queryCompletionBlock = partOperation.queryCompletionBlock
                self.privateDatabase.add(newOp)

                return
            }
            self.progress.completedUnitCount += 1
            print ("Initial Sync - Part Objects Fetched")


        }

        partOperation.database = privateDatabase

        ...
    }

 }

3 个答案:

答案 0 :(得分:0)

这很可能是CloudKit错误并提交错误报告可能是最佳选择。 CloudKit还不是完美的。

答案 1 :(得分:0)

如果我没有在游标块中将查询操作分配给主操作,我通常会遇到大型读取(超过2个游标)的问题。

尝试在~/repos/Mock-Sub $ brewbuild -R reverse dependencies: Test::Module::CheckDep::Version, App::RPi::EnvUI, RPi::DigiPot::MCP4XXXX, Devel::Examine::Subs, PSGI::Hector, File::Edit::Portable, Devel::Trace::Subs Test::Module::CheckDep::Version 5.26.1 :: PASS App::RPi::EnvUI 5.26.1 :: FAIL RPi::DigiPot::MCP4XXXX 5.26.1 :: FAIL Devel::Examine::Subs 5.26.1 :: PASS PSGI::Hector 5.26.1 :: PASS File::Edit::Portable 5.26.1 :: PASS Devel::Trace::Subs 5.26.1 :: PASS

上方添加partOperation = newOp

我不相信你在光标块的末尾需要self.privateDatabase.add(newOp)。我的电话都没有。

看看是否有帮助。

答案 2 :(得分:0)

我发现了这个问题并且它不是CloudKit错误。这对我来说实际上是一种愚蠢的行为。在我的iCloud权利文件中,我有一行明确将iCloud会话设置为" Production"环境而不是"发展"一。我不知道为什么我有那个;我必须在生产公共商店中调试一些东西,忘了在我完成时撤消它。

无论如何,我认为它应该仍然可以正常工作。它可能没有提取我的所有私人记录,因为它们大多数都在开发环境中,但是当我进行调试时,我也有一些保存到生产环境中。此外,我不明白为什么iOS模拟器在通过生产环境时无法从数据库中获取记录。

但只要它现在正在工作,那对我来说很好。