CloudKit iOS 不会获取我想要的所有记录
CloudKit on iOS won't fetch all of my desired records
我的 api 使用 CloudKit 为我的应用程序获取记录,但现在无法正常工作。它只是在一两周前才开始这样做。它从 public 数据库中获取很好,而不是私有数据库。
例如,我有一个名为 "Part" 的记录类型,其中包含一些值,包括 "datestamp" 字段。第一次启动该应用程序时,它应该使用 CKQueryOperation 获取私有数据库中 Part(和其他)的所有记录,然后在后续启动时,它使用 CKFetchRecordZoneChangesOperation 获取任何新记录。在我的个人 iCloud 帐户中,我有超过 1,000 条这样的记录。但是查询操作和获取更改操作只能获取完全相同的 107 条记录,而不能获取更多。这不是 resultLimits 的问题,我已经实现了对 CKQueryCursor 的检查。作为一个实验,我给它一个谓词来只获取日期戳为 2018 年 1 月或更晚的记录——它返回 0 记录。还有另一种记录类型在我的数据库中有 12 条记录,但只有 1 正在同步。
我将同步 class 设计为跨平台 API。它适用于我的 iOS、macOS 和 tvOS 目标。 macOS 目标同步得很好,即使它使用完全相同的代码行。 iOS 和 tvOS 已经运行了将近 2 年。除了现在在 NSOperation subclass 中使用 class 之外,几乎没有任何改变。我试过多个 iPhone、iPad、iOS 模拟器实例、iOS 版本、Xcode 版本。我试过其他 iCloud 帐户。我不知道是什么问题。但是这个错误阻碍了我发布急需的更新。我认为这可能只是 Apple 在开发环境中的一个错误,并且会在 public 版本中正常工作,但我担心禁用我的所有用户。
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 += [[=12=]] }
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
...
}
}
这很可能是 CloudKit 错误,提交错误报告可能是最佳选择。 CloudKit 还没有完善。
如果我不将查询操作分配给游标块中的主要操作,我通常会遇到大量提取(超过 2 个游标)的问题。
尝试在 self.privateDatabase.add(newOp)
的正上方添加 partOperation = newOp
我认为您不需要 return
在游标块的末尾。 None 我的电话有一个。
看看是否有帮助。
我发现了这个问题,它不是 CloudKit 错误。这实际上对我来说有点愚蠢。在我的 iCloud 权利文件中,我有一行明确地将 iCloud 会话设置为 "Production" 环境而不是 "Development" 环境。我不知道为什么我在那里有那个;我一定是在生产 public 商店中调试了一些东西,只是在完成后忘了撤消它。
尽管如此,我认为它应该仍然可以正常工作。它可能没有获取我所有的私人记录,因为它们中的大部分都在开发环境中,但我在调试时也有一些保存到生产环境中。另外,我不明白为什么 iOS 模拟器在通过生产环境时无法从任何一个数据库中获取记录。
但只要它现在能正常工作,我就没问题。
我的 api 使用 CloudKit 为我的应用程序获取记录,但现在无法正常工作。它只是在一两周前才开始这样做。它从 public 数据库中获取很好,而不是私有数据库。
例如,我有一个名为 "Part" 的记录类型,其中包含一些值,包括 "datestamp" 字段。第一次启动该应用程序时,它应该使用 CKQueryOperation 获取私有数据库中 Part(和其他)的所有记录,然后在后续启动时,它使用 CKFetchRecordZoneChangesOperation 获取任何新记录。在我的个人 iCloud 帐户中,我有超过 1,000 条这样的记录。但是查询操作和获取更改操作只能获取完全相同的 107 条记录,而不能获取更多。这不是 resultLimits 的问题,我已经实现了对 CKQueryCursor 的检查。作为一个实验,我给它一个谓词来只获取日期戳为 2018 年 1 月或更晚的记录——它返回 0 记录。还有另一种记录类型在我的数据库中有 12 条记录,但只有 1 正在同步。
我将同步 class 设计为跨平台 API。它适用于我的 iOS、macOS 和 tvOS 目标。 macOS 目标同步得很好,即使它使用完全相同的代码行。 iOS 和 tvOS 已经运行了将近 2 年。除了现在在 NSOperation subclass 中使用 class 之外,几乎没有任何改变。我试过多个 iPhone、iPad、iOS 模拟器实例、iOS 版本、Xcode 版本。我试过其他 iCloud 帐户。我不知道是什么问题。但是这个错误阻碍了我发布急需的更新。我认为这可能只是 Apple 在开发环境中的一个错误,并且会在 public 版本中正常工作,但我担心禁用我的所有用户。
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 += [[=12=]] }
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
...
}
}
这很可能是 CloudKit 错误,提交错误报告可能是最佳选择。 CloudKit 还没有完善。
如果我不将查询操作分配给游标块中的主要操作,我通常会遇到大量提取(超过 2 个游标)的问题。
尝试在 self.privateDatabase.add(newOp)
partOperation = newOp
我认为您不需要 return
在游标块的末尾。 None 我的电话有一个。
看看是否有帮助。
我发现了这个问题,它不是 CloudKit 错误。这实际上对我来说有点愚蠢。在我的 iCloud 权利文件中,我有一行明确地将 iCloud 会话设置为 "Production" 环境而不是 "Development" 环境。我不知道为什么我在那里有那个;我一定是在生产 public 商店中调试了一些东西,只是在完成后忘了撤消它。
尽管如此,我认为它应该仍然可以正常工作。它可能没有获取我所有的私人记录,因为它们中的大部分都在开发环境中,但我在调试时也有一些保存到生产环境中。另外,我不明白为什么 iOS 模拟器在通过生产环境时无法从任何一个数据库中获取记录。
但只要它现在能正常工作,我就没问题。