我是云套件的新手,有人可以帮助我解决错误,因为我正在尝试在我的公共数据库中添加记录并获取此错误。
“坏容器”(5/1014);“无法从容器“iCloud.com.abc.def”的服务器获取容器配置”
谢谢 。
我有一个IOS 8应用程序,它成功地将记录写入其默认的Cloudkit容器.现在我希望在OS X下的不同应用程序中读取和处理这些记录.我已经设置了具有iCloud访问权限的新应用程序,并选中了"指定自定义容器"选项.这已成功找到原始应用程序和我的容器没有错误要在Capabilities界面上修复.
我的所有搜索都告诉我"同一个开发人员签署的两个应用程序可能共享同一个容器"但我找不到的任何教程文档都告诉我如何从自定义容器访问数据.所有示例似乎都以'let container = CKContainer.defaultContainer()'开头.但是,我不想从默认容器访问记录.我想要自定义容器.
Apple文档建议使用init()结构,但这让我感到困惑.这似乎是一个简单的请求.希望有人可以给我一个简单的解决方案.
我的问题与 WWDC 2014 Advanced CloudKit 中命名的“Delta Download”有关。
我正在尝试为我的 Core Data 应用程序进行同步,该应用程序目前仅适用于 iPhone(想想:只有一台设备处于活动状态)。因此,对于目前的大多数情况,基本上该应用程序会将来自同一设备的用户记录存储在云中。
我无法理解基于CKFetchRecordChangesOperationDelta 下载的自定义区域功能。
正如我做对的那样,我们必须CKServerChangeToken维护同步操作(我的意思是只下载那些被其他设备添加/修改/删除的记录),正如 WWDC 上所展示的那样。但是,我无法理解的是,我们只有在 之后才会收到该令牌CKFetchRecordChangesOperation,当我们将记录保存到云端时,我们不会获得新的令牌。
如果我们使用当前可用的令牌进行 fetch(因为它只在 fetch 之后改变),我们会收到从我们之前的保存操作中保存的记录。基本上,我们会获得设备上已有的保存记录。为什么?我在这里遗漏了什么?
如果我们将一些数据播种到云端(从设备 A),设备 B 正在获取区域记录的情况是合理的,但如果设备 A 是?重新下载所有记录?
我recordChangeTag在CKRecord,这是一个属性,我可以用来解决与本地对象的冲突 - 获取的对象(相同或不同的版本),如果是这样,有人可以举出我需要如何执行此操作的示例:保存时将 recordChangeTag 保存到核心数据第一次录制到 CloudKit 还是如何录制?
缺乏文档是一件令人头疼的事。
我只想获取 CloudKit 音乐记录中的 Song_Name 字段。我正在尝试下面的代码,但它仍然获取音乐记录中的所有字段。我想我需要使用 publicDB.add(operation) 方法编译操作,但它不允许我像现在使用 publicDB.perform(query, in....) 那样声明“results”
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: "Musics", predicate: predicate)
let operation = CKQueryOperation(query: query)
operation.desiredKeys = ["Song_Name"]
publicDB.perform(query, inZoneWith: nil) { [unowned self] results, error in
guard error == nil else {
DispatchQueue.main.async {
self.delegate?.errorUpdating(error! as NSError)
print("Cloud Query Error - Refresh: \(error)")
}
return
}
self.items_music.removeAll(keepingCapacity: true)
for record in results! {
let music = Musics(record: record, database: self.publicDB)
self.items_music.append(music)
}
DispatchQueue.main.async {
self.delegate?.modelUpdated()
}
} …Run Code Online (Sandbox Code Playgroud) 我已经更新了现有的 CoreData 应用程序以使用 CloudKit,以便它可以在多个设备之间保持数据同步(对于同一 iCloud 帐户)。
有用!数据同步就好了。
但主 UIViewController 的视图不反映新数据。要查看更改,我必须切换到不同的视图,然后切换回refreshData()在其viewWillAppear()函数中有调用的主视图。然后,它从数据存储中重新读取并显示所有数据(包括在其他设备上更新的数据)。
UIViewController 应该NSPersistentStoreRemoteChange按照viewDidLoad()以下方式观察通知:
override func viewDidLoad() {
super.viewDidLoad()
// NotificationCenter.default.addObserver(self, selector: #selector(handleRemoteChange), name: .NSPersistentStoreRemoteChange, object: AppDelegate.appDelegate().persistentContainer.persistentStoreCoordinator)
NotificationCenter.default.addObserver(self, selector: #selector(handleRemoteChange), name: .NSPersistentStoreRemoteChange, object: nil)
}
Run Code Online (Sandbox Code Playgroud)
但处理函数永远不会被调用:
@objc func handleRemoteChange(notification: Notification) {
print("Handling remote change to data in Collection Controller")
refreshData()
}
Run Code Online (Sandbox Code Playgroud)
该打印语句永远不会打印任何内容,并且在那里设置的断点也永远不会触发。
NSPersistentCloutKitContainer我已将托管对象上下文配置为在创建后立即根据需要合并来自父级的更改:
container.viewContext.automaticallyMergesChangesFromParent = true
Run Code Online (Sandbox Code Playgroud)
该应用程序具有我在网络(和 Stack Overflow)中搜索线索后了解到的所有相关 iCloud 功能和权利,包括:
容器的 persistenceStoreDescription 的NSPersistentStoreRemoteChangeNotificationPostOptionKey选项设置为 true:
container.loadPersistentStores(completionHandler: { (storeDescription, …Run Code Online (Sandbox Code Playgroud) 我正在尝试配置 CoreData+CloudKit 以NSPersistentCloudKitContainer自动将数据同步到 CloudKit 或从 CloudKit 同步数据。
按照Apple 指南,设置一个实体、在 Xcode 中添加适当的功能、在我的 AppDelegate 中设置persistentContainer和就足够简单了。saveContext
我通过 拨打fetch()和save()拨打电话NSManagedObjectContext,并且能够毫无问题地保存和获取记录。我可以在 CloudKit 仪表板中看到它们。
但是,如果我从模拟器中卸载应用程序并重建/重新安装,我的应用程序fetchRequest(没有排序NSPredicate或排序,只是获取所有记录)始终返回一个空列表。我使用相同的 iCloud 帐户,并且尝试了公共和私有数据库范围。如果我创建一条新记录,然后重试我的提取请求,我可以检索该新创建的记录,但永远不会检索任何旧记录。我 100% 确定这些记录仍在 CloudKit 数据库中,因为我可以在 CloudKit Dashboard Web 应用程序上看到它们。
我查看了Apple 的 CoreDataCloudKitDemo应用程序,它能够在卸载/重新安装后从 CloudKit 数据库中获取“Post”实体,所以我知道这是可能的。但是,它使用的是NSFetchedResultsController,这不适用于我的应用程序(我的应用程序是 SpriteKit 游戏)。
我尝试将 CoreData+Cloudkit 代码复制到一个全新的 Xcode 项目中,我可以在那里重现此问题。这是我的代码供参考:
import UIKit
import CoreData
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
lazy var persistentContainer: NSPersistentContainer = {
// Create a …Run Code Online (Sandbox Code Playgroud) 我有一个使用 Core Data + CloudKit 堆栈的应用程序。(核心数据在设备之间同步。)。现在我想在 iOS 14 小部件中显示来自 Core Data 的数据(在 WidgetKit 目标中查看)。
\n我的目标是让小部件中的数据也是来自核心数据的实际数据:即 \xe2\x80\x94 用户更改了设备 A 上的记录,稍后在设备 B(带有小部件)上更改了小部件中表示的记录。
\n我应该怎么做:
\na)为主应用程序目标和小部件目标添加应用程序组功能;并在小部件目标中获取核心数据。
\nb) 在主应用程序目标中获取核心数据,保存到文件(plist?、JSON?),然后在小部件中使用该文件。
\nc)在主应用程序目标中获取核心数据,从小部件目标中获取该数据。(是否可以?)
什么才是最合理的方式呢?感谢您的任何建议。
\n我有一个带有本地存储和云存储的 CoreData 设置,只有后者与 CloudKit 同步。同步本身运行良好。
我正在尝试侦听远程更改通知,以便在来自 CloudKit 的远程更改传入时可以触发设备上的某些进程。我已经NSPersistentStoreRemoteChangeNotificationOptionKey在持久性控制器中设置了密钥,并设置了相应的观察者来侦听此通知。
观察者正确触发远程更改通知,但我的问题是,一旦保存视图上下文,它也会触发设备上产生的任何 CoreData 更改。
如果这是预期的行为,我希望通知本身至少有一些有用的信息,这样我就可以区分更改是由设备上的操作触发还是从 CloudKit 同步。
我做错了什么,或者有其他简单的方法可以在远程更改发生时收到通知吗?
struct PersistenceController {
static let shared = PersistenceController()
let container: NSPersistentCloudKitContainer
init() {
container = NSPersistentCloudKitContainer(name: "MyContainerName")
let storeDirectory = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
// Local
let localUrl = storeDirectory.appendingPathComponent("local.store")
let local = NSPersistentStoreDescription(url: localUrl)
local.configuration = "Local"
// Cloud
let cloudUrl = storeDirectory.appendingPathComponent("cloud.store")
let cloud = NSPersistentStoreDescription(url: cloudUrl)
cloud.configuration = "Cloud"
cloud.cloudKitContainerOptions = NSPersistentCloudKitContainerOptions(containerIdentifier: "my.container.identifier")
cloud.setOption(true …Run Code Online (Sandbox Code Playgroud) 在 iOS 15 的 Xcode 13 beta 中,我收到一条消息,称perform(_:inZoneWith:completionHandler:)(CloudKit) 在 iOS 15 中已弃用并重命名为fetchRecords(matching:inZoneWith:desiredKeys:resultsLimit:completionHandler:)“但是...”
Apple 文档网站未声明此方法已弃用:https://developer.apple.com/documentation/cloudkit/ckdatabase/1449127-perform
Apple 正在展示 iOS 15 的其他弃用(另一种方法):https://developer.apple.com/documentation/cloudkit/ckdatabase/3794331-records/
fetchRecords(matching:inZoneWith:desiredKeys:resultsLimit:completionHandler:)似乎不存在..还..( Value of type 'CKDatabase' has no member 'fetchRecords')
那么,这是否只是一个错误消息,因为它是测试版?我应该担心重写使用的函数perform(_:inZoneWith:completionHandler:)吗?
这是我的函数,我尝试将其改编为 fetchRecords,但它不存在。我尝试适应它,fetch(withQuery:completionHandler:但我有点迷失让它发挥作用..
(该函数只是从iCloud私有数据库中删除记录):
let container = CKContainer(identifier: "MyContainerNameHere")
let recordType = "DBName"
//delete all saved icloud records
let query = CKQuery(recordType: recordType, predicate: NSPredicate(value: true))
container.privateCloudDatabase.perform(query, inZoneWith: nil) { (rec, err) in
if let err = err {
print(err.localizedDescription) …Run Code Online (Sandbox Code Playgroud) 我对如何处理复杂的 Swift 数据类型、它们对变量的赋值以及访问其中的值有点困惑。希望有人能澄清以下问题:
当尝试从 SwiftUI 和 CloudKit 获取数据,并尝试重写 CK 函数以符合 async/await 时,我有以下代码行:
let result = try await container.privateCloudDatabase.records(matching: query)
现在这一行应该从云私有数据库中获取与指定查询匹配的所有记录并返回一些 CKRecords
旧函数的执行方式如下:
container.privateCloudDatabase.perform(query, inZoneWith: nil) { (rec, err) in
for record in rec {
print("Found this record: \(record)")
}
}
Run Code Online (Sandbox Code Playgroud)
这非常有效,因为perform(_:inZoneWith:)会返回一个 CKRecord 和一个错误,它们在语句中被“分开”(rec, err) in并传递到循环中进行迭代。
使用新的 async/await 方法,我尝试简单地等待并将变量分配给找到的所有记录,然后迭代返回的数据,挑选 CKRecords 并执行我想要的任何任务。
我感到困惑的是,当我尝试以多种方式从返回的结果中挑选数据时,我只是收到错误。我不完全理解如何描述返回值的数据结构,我认为这是问题的根本原因。
我尝试了一些方法并收到以下错误消息:
如果我尝试:
let (result, err) = try await container.privateCloudDatabase.records(matching: query)
Run Code Online (Sandbox Code Playgroud)
当我使用时(尝试将 CKRecords 附加到我之前创建的 CKRecords 数组中):
for record in result {
self.myCKRecordArray.append(record)
}
Run Code Online (Sandbox Code Playgroud)
错误消息具体指出: …