motion/cdq/store.rb in cdq-0.1.9 vs motion/cdq/store.rb in cdq-0.1.10

- old
+ new

@@ -1,17 +1,26 @@ module CDQ class CDQStoreManager + STORE_DID_INITIALIZE_NOTIFICATION = 'com.infinitered.cdq.store.did_initialize' + attr_writer :current def initialize(opts = {}) @config = opts[:config] || CDQConfig.default @model_manager = opts[:model_manager] end + def new(opts = {}) + @config = opts[:config] || CDQConfig.default + @model_manager = opts[:model_manager] || CDQ.cdq.models + @icloud = opts[:icloud] || opts[:iCloud] || @config.icloud + @icloud_container = @config.icloud_container + end + def current @current ||= create_store end def reset! @@ -26,39 +35,110 @@ def create_store if invalid? raise "No model found. Can't create a persistent store coordinator without it." else - coordinator = NSPersistentStoreCoordinator.alloc.initWithManagedObjectModel(@model_manager.current) - error = Pointer.new(:object) - options = { NSMigratePersistentStoresAutomaticallyOption => true, - NSInferMappingModelAutomaticallyOption => true } + if @icloud + create_icloud_store + else + create_local_store + end + end + end + + def create_icloud_store + coordinator = NSPersistentStoreCoordinator.alloc.initWithManagedObjectModel(@model_manager.current) + + Dispatch::Queue.concurrent.async { + # get icloud first container url = @config.database_url - mkdir_p File.dirname(url.path) - store = coordinator.addPersistentStoreWithType(NSSQLiteStoreType, - configuration:nil, - URL:url, - options:options, - error:error) - if store.nil? - error[0].userInfo['metadata'] && error[0].userInfo['metadata'].each do |key, value| - NSLog "#{key}: #{value}" + icloud_url = NSFileManager.defaultManager.URLForUbiquityContainerIdentifier(@icloud_container) + if icloud_url + error = Pointer.new(:object) + icloud_url = icloud_url.URLByAppendingPathComponent("data") + error = Pointer.new(:object) + options = { NSMigratePersistentStoresAutomaticallyOption => true, + NSInferMappingModelAutomaticallyOption => true, + NSPersistentStoreUbiquitousContentNameKey => url.path.lastPathComponent.gsub(".", "_"), + NSPersistentStoreUbiquitousContentURLKey => icloud_url, + } + coordinator.lock + store = coordinator.addPersistentStoreWithType(NSSQLiteStoreType, + configuration:nil, + URL:url, + options:options, + error:error) + coordinator.unlock + + if store.nil? + error[0].userInfo['metadata'] && error[0].userInfo['metadata'].each do |key, value| + NSLog "#{key}: #{value}" + end + raise error[0].userInfo['reason'] end - raise error[0].userInfo['reason'] + + else + error = Pointer.new(:object) + options = { NSMigratePersistentStoresAutomaticallyOption => true, + NSInferMappingModelAutomaticallyOption => true } + url = @config.database_url + mkdir_p File.dirname(url.path) + store = coordinator.addPersistentStoreWithType(NSSQLiteStoreType, + configuration:nil, + URL:url, + options:options, + error:error) + if store.nil? + error[0].userInfo['metadata'] && error[0].userInfo['metadata'].each do |key, value| + NSLog "#{key}: #{value}" + end + raise error[0].userInfo['reason'] + end end - coordinator + Dispatch::Queue.main.after(0) { + # This block is executed in a next run loop. + # So the managed object context has a store coordinator in this point. + NSNotificationCenter.defaultCenter.postNotificationName(STORE_DID_INITIALIZE_NOTIFICATION, object:coordinator) + } + } + coordinator + end + + def create_local_store + coordinator = NSPersistentStoreCoordinator.alloc.initWithManagedObjectModel(@model_manager.current) + error = Pointer.new(:object) + options = { NSMigratePersistentStoresAutomaticallyOption => true, + NSInferMappingModelAutomaticallyOption => true } + url = @config.database_url + mkdir_p File.dirname(url.path) + store = coordinator.addPersistentStoreWithType(NSSQLiteStoreType, + configuration:nil, + URL:url, + options:options, + error:error) + if store.nil? + error[0].userInfo['metadata'] && error[0].userInfo['metadata'].each do |key, value| + NSLog "#{key}: #{value}" + end + raise error[0].userInfo['reason'] end + Dispatch::Queue.main.after(0) { + # This block is executed in a next run loop. + # So the managed object context has a store coordinator in this point. + NSNotificationCenter.defaultCenter.postNotificationName(STORE_DID_INITIALIZE_NOTIFICATION, object:coordinator) + } + coordinator end - + def mkdir_p dir error = Pointer.new(:object) m = NSFileManager.defaultManager r = m.createDirectoryAtPath dir, withIntermediateDirectories:true, attributes:nil, error:error unless r NSLog "#{error[0].localizedDescription}" raise error[0].localizedDescription end end - + end end