0

我想使用 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 仪表板时,我看到已经创建了一个容器,但 datas 文件夹中没有任何记录。

我的设备之间没有任何同步。

你能告诉我哪里错了吗??

谢谢你。

4

2 回答 2

0

解决我的问题:

  1. 将代码放在正确的位置(在 AppDelegate 中)。

  2. 安装 Ensembles 的最新更新(1.7.1 而不是 1.7)。

就这样!谢谢德鲁。

只有一件事仍然很奇怪:当我在一个设备中添加一个对象时,它会在另一个设备上同步,但是当我删除一个对象时,它不会在另一个设备上被删除,而是在第一个设备上再次创建。

于 2017-10-16T08:01:02.893 回答
0

通过将设置代码放入一个动作中,我猜你每次按下按钮时都会创建一个新的 Ensemble(和 Core Data 堆栈)。您应该设置堆栈和集成一次,也许在启动时viewDidLoad,并将其保存在一个属性中。

请注意,您第一次调用时sync,它会“吸血”。这涉及导入您的本地数据,但它不会上传任何内容。第二次调用时sync,它会从云端下载数据并上传。因此,您需要调用sync两次——使用相同的集成对象——才能在 CloudKit Web 界面中看到任何数据。

另请注意,您只能从登录用户查看 CloudKit 中的数据。因此,除非您使用正在测试的帐户登录,否则您仍然看不到任何内容。

于 2017-10-16T06:13:36.227 回答