我想使用Ensembles Framework将我的核心数据与Swift同步。
但我有一些困难......
我尝试这样做:(类似于github上的示例) 我使用按钮启动任务:
class ReglagesVC: UIViewController,UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate,CDEPersistentStoreEnsembleDelegate {
@IBAction func IcloudSynch(_ sender: UIButton) {
CDESetCurrentLoggingLevel(CDELoggingLevel.verbose.rawValue)
// Setup Core Data Stack
self.setupCoreData()
// Setup Ensemble
let modelURL = Bundle.main.url(forResource: "Mes_Vide_os", withExtension: "momd")
cloudFileSystem = CDEICloudFileSystem(ubiquityContainerIdentifier: nil)
ensemble = CDEPersistentStoreEnsemble(ensembleIdentifier: "Mes_Vide_os", persistentStore: storeURL, managedObjectModelURL: modelURL!, cloudFileSystem: cloudFileSystem)
ensemble.delegate = self
// Listen for local saves, and trigger merges
NotificationCenter.default.addObserver(self, selector:#selector(localSaveOccurred(_:)), name:NSNotification.Name.CDEMonitoredManagedObjectContextDidSave, object:nil)
NotificationCenter.default.addObserver(self, selector:#selector(cloudDataDidDownload(_:)), name:NSNotification.Name.CDEICloudFileSystemDidDownloadFiles, object:nil)
// Sync
self.sync(nil)
}
//ENSEMBLES
// MARK: Notification Handlers
func localSaveOccurred(_ notif: Notification) {
self.sync(nil)
}
func cloudDataDidDownload(_ notif: Notification) {
self.sync(nil)
}
let appDelegate = UIApplication.shared.delegate as! AppDelegate
var storeDirectoryURL: URL {
return try! FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
}
var storeURL: URL {
return self.storeDirectoryURL.appendingPathComponent("store.sqlite")
}
var managedObjectContext : NSManagedObjectContext!
func setupCoreData() {
let modelURL = Bundle.main.url(forResource: "Mes_Vide_os", withExtension: "momd")//"momd"
let model = NSManagedObjectModel(contentsOf: modelURL!)
try! FileManager.default.createDirectory(at: self.storeDirectoryURL, withIntermediateDirectories: true, attributes: nil)
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: model!)
let options = [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true]
try! coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: self.storeURL, options: options)
managedObjectContext = appDelegate.persistentContainer.viewContext
managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
managedObjectContext.persistentStoreCoordinator = coordinator
managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
}
// MARK: Ensembles
var cloudFileSystem: CDECloudFileSystem!
var ensemble: CDEPersistentStoreEnsemble!
func sync(_ completion: (() -> Void)?) {
//let viewController = self.window?.rootViewController as! ReglagesVC
//self.activityIndicator?.startAnimating()
if !ensemble.isLeeched {
ensemble.leechPersistentStore {
error in
print("LEECH FINI___________________________")
completion?()
}
}
else {
ensemble.merge {
error in
print("MERGE FINI___________________________")
completion?()
}
}
}
func persistentStoreEnsemble(_ ensemble: CDEPersistentStoreEnsemble, didSaveMergeChangesWith notification: Notification) {
managedObjectContext.performAndWait {
self.managedObjectContext.mergeChanges(fromContextDidSave: notification)
}
}
func persistentStoreEnsemble(_ ensemble: CDEPersistentStoreEnsemble!, globalIdentifiersForManagedObjects objects: [Any]!) -> [Any]! {
let Films = objects as! [BaseFilms]
print("films map")
return Films.map { $0.id }
}
}
当我登录我的cloudkit仪表板时,我看到已经创建了一个容器,但是数据文件夹中没有任何记录。
我的设备之间没有任何同步。
你能告诉我我错在哪里吗?
谢谢。
答案 0 :(得分:0)
通过将设置代码放在一个动作中,我猜你每次按下按钮都会创建一个新的Ensemble(和Core Data堆栈)。您应该设置堆栈和整合一次,可能在viewDidLoad
中启动,并将其保存在属性中。
请注意,第一次拨打sync
时,它会“水蛭”。这涉及导入本地数据,但不会上传任何内容。第二次拨打sync
时,它会从云下载数据并上传。因此,您需要使用相同的集合对象调用sync
两次 - 然后才能在CloudKit Web界面中看到任何数据。
另请注意,您只能从登录用户中查看CloudKit中的数据。因此,除非您使用您正在测试的帐户登录,否则您仍然看不到任何内容。
答案 1 :(得分:0)
解决我的问题:
将代码放在正确的位置(在AppDelegate中)。
安装最新的Ensembles更新(1.7.1而不是1.7)。
这就是全部!谢谢Drew。
还有一件事仍然很奇怪:当我在一个设备中添加一个对象时,它会在另一个上同步但当我删除一个对象时,它不会在另一个设备上删除并再次创建在第一台设备上。