斯威夫特合奏建立与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]
}
对你有好处!你应该提供它为什么不起作用的细节,以及为什么当你以前没有做过什么时,它会起作用......然后接受它作为答案。 –
谢谢建议合奏乔迪..它的作品完美。没有更多的iCloud头痛。该应用只是同步,并很好地同步。 – DogCoffee
:-) :-) :-) :-) –