Swift Ensembles成立& ubiquityContainerIdentifier

时间:2015-10-18 22:48:52

标签: swift ensembles

这本书说明了,

  

“整体标识符用于跨设备匹配商店。它是   重要的是,这对于整体中的每个商店都是一样的。“

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

这对所有用户来说都必须是唯一的吗?还是只是为了我的申请?

如果有人有一个 Swift 版本的设置Ensembles会很棒。

到目前为止,我只需要这一切吗?

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)

不是零

1 个答案:

答案 0 :(得分:3)

让它最终发挥作用 - 在1.0 Git

中找到了示例应用

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

支持此框架 - 购买合奏2,如果你喜欢ver 1。

更新..更简单

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

这是让合奏团工作的附加功能。

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]
}