2015-10-18 100 views
2

這本書的狀態,斯威夫特合奏建立與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) 

並非是零

回答

3

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

我相信我是在快速吮吸 - 沒有給予足夠的時間來完成設置過程。

支持這個框架 - 買合奏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

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