Swift Ensembles 设置和 ubiquityContainerIdentifier
Posted
技术标签:
【中文标题】Swift Ensembles 设置和 ubiquityContainerIdentifier【英文标题】:Swift Ensembles Set Up & ubiquityContainerIdentifier 【发布时间】:2015-10-18 22:48:52 【问题描述】:书上说,
“集成标识符用于匹配跨设备的商店。这是 重要的是这对于整体中的每个商店都是相同的。”
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)
不是零
【问题讨论】:
【参考方案1】:最终成功了 - 在 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]
【讨论】:
对你有好处!您应该提供它为什么不起作用的详细信息,以及为什么它在您以前没有的情况下起作用……然后接受它作为答案。 感谢 Jody 推荐合奏.. 效果很好。没有更多的 iCloud 头痛。该应用程序只是同步,并且同步良好。以上是关于Swift Ensembles 设置和 ubiquityContainerIdentifier的主要内容,如果未能解决你的问题,请参考以下文章
在使用 Ensembles 进行 CoreData 和 iCloud 同步之前,我是不是需要任何 iCloud 设置?
Core Data 与 Ensembles 的 iCloud 同步
将 Ensembles 添加到现有 Coredata / iCloud 应用程序的步骤