斯威夫特合奏建立与ubiquityContainerIdentifier

问题描述:

这本书的状态,斯威夫特合奏建立与ubiquityContainerIdentifier

“合奏标识,用于跨设备匹配店。这是在合奏每家商店同样是 重要。”

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

这是否必须是唯一的所有用户?或只是为了我的应用程序?

如果有人有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) 

并非是零

得到它的工作结束 - 在中找到示例应用程序

我相信我是在快速吮吸 - 没有给予足够的时间来完成设置过程。

支持这个框架 - 买合奏2,如果你喜欢的版本1.

更新..更简单的方法

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

这是额外获得合奏工作。

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

我的第一种方式

这是斯威夫特,有一些额外

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的每个应用程序 必须具有无处不在的容器标识。当您启用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] 
} 
+0

对你有好处!你应该提供它为什么不起作用的细节,以及为什么当你以前没有做过什么时,它会起作用......然后接受它作为答案。 –

+0

谢谢建议合奏乔迪..它的作品完美。没有更多的iCloud头痛。该应用只是同步,并很好地同步。 – DogCoffee

+0

:-) :-) :-) :-) –