2

书中指出,

“整体标识符用于匹配跨设备的商店。重要的是,对于整体中的每家商店来说,这都是相同的。”</p>

let ensembleFileSystem = CDEICloudFileSystem(ubiquityContainerIdentifier: "???")

这是否需要对所有用户都是唯一的?或者只是为了我的申请?

如果有人有关于如何设置 Ensembles的Swift版本,那就太好了。

到目前为止,我所需要的就是这些吗?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    let ensembleFileSystem = CDEICloudFileSystem(ubiquityContainerIdentifier: "???")

    let modelURL = NSBundle.mainBundle().URLForResource("DataModel", withExtension: "momd")!
    let url = applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")

    let ensemble = CDEPersistentStoreEnsemble(ensembleIdentifier: "mainstore", persistentStoreURL: url, managedObjectModelURL: modelURL, cloudFileSystem: ensembleFileSystem!)


    if !ensemble.leeched {
        ensemble.leechPersistentStoreWithCompletion { (error) -> Void in
            if error != nil {
                print("cannot leech")
                print(error!.localizedDescription)
            }
        }
    }

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "syncWithCompletion:", name: CDEMonitoredManagedObjectContextDidSaveNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "syncWithCompletion:", name: CDEICloudFileSystemDidDownloadFilesNotification, object: nil)

    return true
}

func syncWithCompletion(notification:NSNotification) {
    print("synced \(notification)")
    managedObjectContext.mergeChangesFromContextDidSaveNotification(notification)
}

缺少某些东西我收到此错误日志

User is not logged into iCloud

尽管登录很明显

print(NSFileManager.defaultManager().ubiquityIdentityToken)

不为零

4

1 回答 1

3

让它最终工作 - 在1.0 Git中找到示例应用程序

我相信我正在快速地汲取 - 没有给设置过程足够的时间来完成。

支持这个框架 - 如果你喜欢第 1 版,请购买 ensembles 2。

更新..更简单的方法

我只是使用苹果提供的普通核心数据堆栈。

这是使合奏正常工作的附加功能。

var ensemble:CDEPersistentStoreEnsemble!

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    let file = CDEICloudFileSystem(ubiquityContainerIdentifier: nil)
    let modelURL = NSBundle.mainBundle().URLForResource("DataModel", withExtension: "momd")!
    let storeurl = self.applicationDocumentsDirectory.URLByAppendingPathComponent("store.sqlite")
    ensemble = CDEPersistentStoreEnsemble(ensembleIdentifier: "MyStoreName", persistentStoreURL: storeurl, managedObjectModelURL: modelURL, cloudFileSystem: file)
    ensemble.delegate = self

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "localSaveOccurred:", name: CDEMonitoredManagedObjectContextDidSaveNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "cloudDataDidDownload:", name: CDEICloudFileSystemDidDownloadFilesNotification, object: nil)

    syncWithCompletion { completed in
        if completed {
            print("SUCCESSS")
        }
        else {
            print("FAIL")
        }
    }

    return true
}

// MARK: - Sync

func applicationDidEnterBackground(application: UIApplication) {
    print("Did Enter Background Save from App Delegate")

    let identifier = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler(nil)
    saveContext()

    syncWithCompletion { (completed) -> Void in
        if completed {
            UIApplication.sharedApplication().endBackgroundTask(identifier)
        }
    }
}

func applicationWillEnterForeground(application: UIApplication) {
    syncWithCompletion { (completed) -> Void in

    }
}

func localSaveOccurred(note:NSNotification) {
    syncWithCompletion { (completed) -> Void in

    }
}

func cloudDataDidDownload(note:NSNotification) {
    syncWithCompletion { (completed) -> Void in
        print("items from iCloud arrived")
    }
}

func syncWithCompletion(completion:(completed:Bool) -> Void) {

    UIApplication.sharedApplication().networkActivityIndicatorVisible = true

    if !ensemble.leeched {
        ensemble.leechPersistentStoreWithCompletion(nil)
    }
    else {
        ensemble.mergeWithCompletion{ error in
            if error != nil {
                print("cannot merge \(error!.localizedDescription)")
                UIApplication.sharedApplication().networkActivityIndicatorVisible = false
                completion(completed: false)
            }
            else {
                print("merged")
                UIApplication.sharedApplication().networkActivityIndicatorVisible = false
                completion(completed: true)
            }
        }
    }
}

// MARK: - Ensemble Delegate Methods

func persistentStoreEnsemble(ensemble: CDEPersistentStoreEnsemble!, didSaveMergeChangesWithNotification notification: NSNotification!) {

    managedObjectContext.performBlockAndWait { () -> Void in
        self.managedObjectContext.mergeChangesFromContextDidSaveNotification(notification)
    }
}

func persistentStoreEnsemble(ensemble: CDEPersistentStoreEnsemble!, globalIdentifiersForManagedObjects objects: [AnyObject]!) -> [AnyObject]! {
    return (objects as NSArray).valueForKeyPath("uniqueIdentifier") as! [AnyObject]
}

我的第一种方式

这是在 Swift 中的,还有一些额外的

var ensemble:CDEPersistentStoreEnsemble!
var cloudFileSystem:CDEICloudFileSystem!
var managedObjectContext: NSManagedObjectContext!

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.

    setUpCoreData()

    let modelURL = NSBundle.mainBundle().URLForResource("YourDataModel", withExtension: "momd")!
    cloudFileSystem = CDEICloudFileSystem(ubiquityContainerIdentifier:"USE_YOUR_APPS_REVERSE DOMAIN NAME HERE")

来自开发者:RE ubiquityContainerIdentifier

这不是 Ensembles 本身的一部分。它来自 iCloud。每个使用 iCloud 的应用程序都必须有一个无处不在的容器 ID。启用 iCloud 后,您可以在应用设置中找到它。每个应用程序都是唯一的,我们仅在您选择 iCloud(例如,不是 Dropbox)时使用它。

    ensemble = CDEPersistentStoreEnsemble(ensembleIdentifier: "store", persistentStoreURL: storeURL(), managedObjectModelURL: modelURL, cloudFileSystem: cloudFileSystem!)
    ensemble.delegate = self

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "localSaveOccurred:", name: CDEMonitoredManagedObjectContextDidSaveNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "cloudDataDidDownload:", name: CDEICloudFileSystemDidDownloadFilesNotification, object: nil)

    syncWithCompletion { completed in
        if completed {
            print("SUCCESSS")
        }
        else {
            print("FAIL")
        }
    }

    return true
}

// MARK: - Core Data Stack

func setUpCoreData() {

    let modelURL = NSBundle.mainBundle().URLForResource("DataModel", withExtension: "momd")!
    guard let model = NSManagedObjectModel(contentsOfURL: modelURL) else { fatalError("cannot use model") }

    do {
        try NSFileManager.defaultManager().createDirectoryAtURL(storeDirectoryURL(), withIntermediateDirectories: true, attributes: nil)
    }
    catch {
        fatalError("cannot create dir")
    }

    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: model)
    //NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption: @YES, NSInferMappingModelAutomaticallyOption: @YES};

    let failureReason = "There was an error creating or loading the application's saved data."

    do {
        try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL(), options: nil)

        managedObjectContext = NSManagedObjectContext.init(concurrencyType: .MainQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = coordinator
        managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy

    } catch {
        // Report any error we got.
        var dict = [String: AnyObject]()
        dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
        dict[NSLocalizedFailureReasonErrorKey] = failureReason

        dict[NSUnderlyingErrorKey] = error as NSError
        let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
        // Replace this with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
        abort()
    }
}

func storeDirectoryURL() -> NSURL {

    let directoryURL = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)
    return directoryURL
}

func storeURL() -> NSURL {
    let url = storeDirectoryURL().URLByAppendingPathComponent("store.sqlite")
    return url
}


// MARK: - Sync

func applicationDidEnterBackground(application: UIApplication) {
    print("Did Enter Background Save from App Delegate")

    let identifier = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler(nil)
    saveContext()

    syncWithCompletion { (completed) -> Void in
        if completed {
            UIApplication.sharedApplication().endBackgroundTask(identifier)
        }
    }
}

func applicationWillEnterForeground(application: UIApplication) {
    syncWithCompletion { (completed) -> Void in

    }
}

func localSaveOccurred(note:NSNotification) {
    syncWithCompletion { (completed) -> Void in

    }
}

func cloudDataDidDownload(note:NSNotification) {
    syncWithCompletion { (completed) -> Void in

    }
}

func syncWithCompletion(completion:(completed:Bool) -> Void) {

    if !ensemble.leeched {
        ensemble.leechPersistentStoreWithCompletion { error in
            if error != nil {
                print("cannot leech \(error!.localizedDescription)")
                completion(completed: false)
            }
            else {
                print("leached!!")
                completion(completed: true)
            }
        }
    }
    else {
        ensemble.mergeWithCompletion{ error in
            if error != nil {
                print("cannot merge \(error!.localizedDescription)")
                completion(completed: false)
            }
            else {
                print("merged!!")
                completion(completed: true)
            }
        }
    }
}

// MARK: - Ensemble Delegate Methods

func persistentStoreEnsemble(ensemble: CDEPersistentStoreEnsemble!, didSaveMergeChangesWithNotification notification: NSNotification!) {

    print("did merge changes with note")


    managedObjectContext.mergeChangesFromContextDidSaveNotification(notification)
}

func persistentStoreEnsemble(ensemble: CDEPersistentStoreEnsemble!, globalIdentifiersForManagedObjects objects: [AnyObject]!) -> [AnyObject]! {
    return (objects as NSArray).valueForKeyPath("uniqueIdentifier") as! [AnyObject]
}
于 2015-10-19T04:28:55.413 回答