这本书说明了,
“整体标识符用于跨设备匹配商店。它是 重要的是,这对于整体中的每个商店都是一样的。“
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)
不是零
答案 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]
}