RubyCocoa : DocumentBasedRubyCoreData

There are several gottachs when working with NSDocument CoreData and RubyCocoa. You have to set up a few methods on your (using the default given to you by XCode) MyDocument class to make it work in the correct manner....

I found a really good sample that helped me put this together, its an NSPersistanceDocument sample from apple, you can download the source at the NSPersistanceDocument reference

# called on every document, either saved and re-open, or
 # docs that have been created afresh
 def init
   super_init()
 end
 
 # (id)
 # only called when a new document is created
 def initWithType_error(type, error)
   super_init()
	if self != nil
	  #@yourobjectname = NSManagedObject.alloc.init()
	  self.setServer(NSEntityDescription.insertNewObjectForEntityForName_inManagedObjectContext("YourEntity",self.managedObjectContext))
	  
	  # To avoid undo registration for this insertion, removeAllActions on the undoManager.
		# First call processPendingChanges on the managed object context to force the undo registration
		# for this insertion, then call removeAllActions.
	  self.managedObjectContext().processPendingChanges()
	  self.managedObjectContext().undoManager().removeAllActions()
	  self.updateChangeCount(:NSChangeCleared)
	end
   return self
 end
 
 # this method is critical as it lets the application re-open documents that were saved as we are only
 # a single managed object and subsequent entity in the model.
 # called by core data when a document is re-opened
 # (bool)
 def configurePersistentStoreCoordinatorForURL_ofType(url, type, error)
   # (bool)
	ok = super_configurePersistentStoreCoordinatorForURL_ofType_error(url, type, error) 
   if ok
	  coordinator = self.managedObjectContext().persistentStoreCoordinator()
	  pStore = coordinator.persistentStoreForURL(url)
	  
	  
	  #  configurePersistentStoreCoordinatorForURL is called when document reopened
		#  Check for existing metadata to avoid overwriting unnecessarily
	  existingMetadata = coordinator.metadataForPersistentStore(pStore).objectForKey('kMDItemKeywords')
	  p existingMetadata
	  
	  if existingMetadata == nil
	    ok = self.setMetadataForStoreAtURL(url)
	  end
	  
	  # return the bool
	  return ok
	end
 end

 # (yourobject object)
 def setServer(aObject)
	if @yourobjectname != aObject
	  @yourobjectname = nil
	  @yourobjectname = aObject.retain
	end
 end


It is very important you define all these init methods... as straight from the Apple documentation it says:

The initializers of NSDocument are another issue for subclasses. The init method is the designated initializer, and it is invoked by the other initializers initWithType:error: and initWithContentsOfURL:ofType:error:. If you need to perform initializations that must be done when creating new documents but should not be done when opening existing documents, override initWithType:error:. If you have any initializations that apply only to documents that are opened, you should override initWithContentsOfURL:ofType:error:. If you have general initializations, you should, of course, override init. In both cases, be sure to invoke the superclass implementation as the first thing.

If you override init, make sure that your override never returns nil. Doing so could cause a crash (in some versions of the Application Kit) or presentation of a less than useful error message. If, for example, you want to prevent the creation or opening of documents under circumstances unique to your application, override a specific NSDocumentController method instead.
© 2001-2007 The RubyCocoa Project. Powered by Wikka Wakka Wiki 1.1.6.3
SourceForge.net Logo
Page was generated in 0.0759 seconds