我想查询当前用户创建的所有记录。我可以成功获取当前用户的 CKRecordID,但我似乎无法正确查询它。下面是我正在使用的代码。我究竟做错了什么?
[[CKContainer defaultContainer] fetchUserRecordIDWithCompletionHandler:^(CKRecordID *recordID, NSError *error) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"creatorUserRecordID = %@", recordID];
CKQuery *query = [[CKQuery alloc] initWithRecordType:@"MyEntity" predicate: predicate];
[database performQuery:query inZoneWithID:nil completionHandler:^(NSArray *results, NSError *error) {
//results are empty
}];
}];
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我在数据库中创建了几条“MyEntity”记录。
我正在尝试根据用户的用户名获取用户的值。我能够使用以下方法获得正确的用户:
class func getByUsername(username: String, callback: (records: [CKRecord]) -> ()){
getSummary(NSPredicate(format: "Username == %@", username)){(records: [CKRecord]) -> Void in
callback(records: records)
}
}
class func getSummary(predicate: NSPredicate, callback: (records: [CKRecord]) -> ()){
let query = CKQuery(recordType: "UserInfo", predicate: predicate)
let queryOperation = CKQueryOperation(query: query)
queryOperation.desiredKeys = ["ID"]
var records = [CKRecord]()
queryOperation.recordFetchedBlock = {record in records.append(record)}
queryOperation.queryCompletionBlock = {_ in callback(records: records)}
CKContainer.defaultContainer().publicCloudDatabase.addOperation(queryOperation)
}
Run Code Online (Sandbox Code Playgroud)
然后我可以通过调用以下命令来获取正确的记录:
getByUsername("Username"){(records: [CKRecord]) -> Void in
var record: CKRecord = records[0]
}
Run Code Online (Sandbox Code Playgroud)
我还可以通过使用获得正确的ID
var id: String …Run Code Online (Sandbox Code Playgroud) 我了解了如何在 CloudKit 仪表板中创建记录类型并一次添加一个记录。我想尝试添加几百条记录进行测试。有没有办法将 CSV 或 JSON 文件导入仪表板?
我想确保我理解正确ubiquityIdentityToken。
每个 iCloud 帐户在每个设备上获取的 ubiquityIdentityToken 在该设备上将是一致且唯一的,但在不同设备之间可能会不一致。
这是真的?
有关 的 Apple 文档,请参阅此处ubiquityIdentityToken。
我正在比较 CKRecord 的版本,使用recordChangeTag,我看到随着时间的推移,值从n9(2 个字符)更改为1c1(3 个字符)。
在苹果文档中:
在您自己的代码中,您可以使用更改标记来区分同一记录的两个不同版本。
我想问一下:
我正在使用 MacCatalyst 将 iOS/iPadOS 应用程序移植到 MacOS。该应用程序以所有方式使用 CloudKit 和函数,除了一个:当从另一台设备提交 CloudKit 更新时,不会在 MacOS 版本上调用UIApplicationDelegate方法 。didReceiveRemoteNotification
在应用程序中起作用的事情:
CKDatabaseOperation向 CloudKit提交包括更新和订阅在内的 sUIApplicationDelegate方法在调用时didRegisterForRemoteNotificationsWithDeviceToken触发并UIApplication.isRegisteredForRemoteNotifications返回 trueUIApplication.registerForRemoteNotificationsCKSubscription.NotificationInfo调用在 MacOS 中正确显示的警报通知UNUserNotificationCenterDelegate方法,willPresent当调用警报通知并且应用程序在前台时didReceiveRemoteNotification 在 iOS 和 iPad(物理设备)上有没有人在使用 MacCatalyst 时调用过UIApplicationDelegate方法didReceiveRemoteNotification?
更新:应用程序最终didReceiveRemoteNotification在发送更新 30 分钟后触发该方法,但在其他更新中,该方法即使在数小时后也不会触发。有任何想法吗?
假设我们有一个有效的 NSPersistentCloudKitContainer 和一个名为 Item 的 CoreData 实体。假设我们想要在 iOS、iPad 和 Mac 应用程序之间同步。
我观看了有关同步 CoreData 和 CloudKit 的 WWDC 会议,并在我的 SwiftUI 应用程序中实现了基本同步。它可以工作,数据会发送到所有 3 台设备并自动同步。
但是在 Mac 上,如果不重新加载视图(以及在模拟器中(因为它们没有收到推送通知),数据就不会出现。它来了,但没有自动刷新。我还测试了模拟器到真实设备,有时它会自动同步,有时我需要重新打开应用程序才能看到更改。
我很好奇是否有一种可以与 NSPersistentCloudKitContainer 一起使用的强制获取方法。或者也许有人知道在使用 NSPersistentCloudKitContainer 和 SwiftUI 时手动重新获取数据的解决方法?
我还想在新数据开始出现时显示一个活动指示器,但不确定在代码中从哪里开始获取获取点?
我使用了 Apple 提供的这个 UIKit示例代码,并将其调整为在 SwiftUI 中工作。我还阅读了此处的所有文档。
这是我使用的persistentContainer代码:
lazy var persistentContainer: NSPersistentCloudKitContainer = {
let container = NSPersistentCloudKitContainer(name: "AppName")
container.persistentStoreDescriptions.first?.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
} …Run Code Online (Sandbox Code Playgroud) core-data ios cloudkit swiftui nspersistentcloudkitcontainer
当 NSPersistentCloudKitContainer 完成同步时如何得到通知?
我对上传Core Data 更改完成感兴趣,因为如果从服务器下载更改,Core Data 可以轻松通知。
我的应用程序使用 CoreData 和 iCloud 作为后端。多个设备可以访问 iCloud 数据库,因此.public。
本地 CoreData 存储与 iCloud 使用NSPersistentCloudKitContainer.
我根据Apple 的建议使用历史跟踪。
在那里,Apple 建议在可能的情况下修剪历史记录。他们说
由于持久历史跟踪事务会占用磁盘空间,因此请确定清除策略以在不再需要它们时将其删除。在修剪历史记录之前,单个看门人应确保您的应用程序及其客户端已经使用了他们需要的历史记录。
最初这也是在 26:10 开始的WWDC 2017 演讲中提出的。
我的问题是:我如何实现这个单一的看门人?
我认为这个想法是单个实例知道应用程序的每个用户最后一次同步他们的设备的时间。如果是这样,则可以修剪该日期之前的交易历史记录。
但是,如果用户同步了本地数据,然后很长时间不再使用该应用程序怎么办?在这种情况下,在该用户再次同步本地数据之前,无法修剪历史记录。所以历史数据可以任意增长。在我看来,这是一个我不知道如何解决的核心问题。
上面引用的 Apple 文档建议:
与获取历史记录类似,您可以使用 deleteHistory(before:) 删除早于令牌、交易或日期的历史记录。例如,您可以删除超过 7 天的所有事务。
但这并不能解决我心中的问题。
除了这个一般问题,我的想法是在公共 iCloud 数据库中有一个 iCloud 记录类型,它直接为每个设备存储(即没有 CoreData)本地数据库更新的最后日期。由于所有设备都可以读取这些记录,因此很容易确定所有本地数据库的最后一次更新时间,并且我可以在此日期之前修剪历史记录。
这是处理问题的正确方法吗?
我试图在userDidAcceptCloudKitShareWith被调用时得到通知。传统上这是在 中调用的,App Delegate但是因为我正在构建一个 iOS 14+App用作我的根对象。关于如何添加userDidAcceptCloudKitShareWith到我的 App 类,我还没有找到任何文档,所以我正在UIApplicationDelegateAdaptor使用一个App Delegate类,但是它似乎userDidAcceptCloudKitShareWith从来没有被调用过?
import SwiftUI
import CloudKit
// Our observable object class
class ShareDataStore: ObservableObject {
static let shared = ShareDataStore()
@Published var didRecieveShare = false
@Published var shareInfo = ""
}
@main
struct SocialTestAppApp: App {
@StateObject var shareDataStore = ShareDataStore.shared
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView().environmentObject(shareDataStore)
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate { …Run Code Online (Sandbox Code Playgroud) cloudkit ×10
ios ×6
core-data ×3
nspersistentcloudkitcontainer ×3
swift ×3
icloud ×2
macos ×2
swiftui ×2
ckrecord ×1
json ×1
mac-catalyst ×1
macos-sierra ×1
pruning ×1