Nspersistentdocument Core Data Tutorial For Mac



  1. Core Data Macos
  2. Nspersistentdocument Core Data Tutorial For Mac Os

Core Data Persistent Packages revisited

For
  1. Introduction to Core Data, Part IV Storing Fetch Requests in your Data Model. By Jeff LaMarche. In the last Core Data article we talked about creating Fetch Requests programmatically using format strings and predicates. Using format strings to create Fetch Requests is a little bit inelegant, although it does give you a tremendous amount of.
  2. Introduction to Core Data, Part IV Storing Fetch Requests in your Data Model. By Jeff LaMarche. In the last Core Data article we talked about creating Fetch Requests programmatically using format strings and predicates. Using format strings to create Fetch Requests is a little bit inelegant, although it does give you a tremendous amount of.
Nspersistentdocument

19 July 2007

This tutorial teaches ASP.NET Core MVC and Entity Framework Core with controllers and views. Razor Pages is an alternative programming model. For new development, we recommend Razor Pages over MVC with controllers and views. Some developers prefer to use one pattern throughout the data model. In this tutorial, the variation illustrates that. In this video i'm going to show how to insert delete and update data in core data and embedded with navigation and list view in SwiftUI. My Xcode Version is 11.0 My mac OS Version is 10.14.6.

This post is a follow-up to another post I wrote on the very same subject. I am showing here the full implementation of a NSPersistentDocument based class that allows to use package documents embedding a Core Data store.

I short, what this post adds to the previous one is:

Core Data Macos

  • improved encapsulation;
  • NSDocumentController subclass to correctly handle the Recent Document menus;
  • fixed a problem with NSError handling, though still not doing any proper error management.

Those improvements originated from a discussion with Tim Perrett in the cocoa-dev mailing list and from a comment by Laurent Sansonetti to my original post. Thanks to both.

PersistentPackageDocument Class

The PersistentPackageDocument class can be used as a base class for your document classes whenever you want them use a document package embedding the actual Core Data data store. PersistentPackageDocument derives from NSPersistentDocument and overrides four methods: initWithContentsOfURL_ofType_error, writeToURL_ofType_forSaveOperation_originalContentsURL_error, readFromURL_ofType_error, displayname. Here’s the code:

Nspersistentdocument Core Data Tutorial For Mac


class PersistentPackageDocument < OSX::NSPersistentDocument

#-- returns the document name to display in the window title
def displayName
if (fileURL)
documentNameFromDataStoreURL(fileURL)
else
'Untitled'
end
end

#-- returns the package document path by stripping the dataStoreName component
#-- from the data store URL; used in displayName
def documentNameFromDataStoreURL(url)
/([^/]+)/?$/ =~ url.relativePath.gsub(/#{dataStoreName}$/, ')
$1 + ' - View'
end

def dataStoreURLFromPackageURL(url)
dataStorePath = url.relativePath.stringByAppendingPathComponent(dataStoreName)
OSX::NSURL.fileURLWithPath(dataStorePath)
end

def readFromURL_ofType_error(url, type, errorPtr)
path=url.relativePath
if (!OSX::NSFileManager.defaultManager.fileExistsAtPath_isDirectory(path, nil))
#-- YOUR ERROR MANAGEMENT HERE
end
result = super_readFromURL_ofType_error(url, type, nil)
if (!result)
#-- SET ERROR INFORMATION TO BE RETURNED VIA errorPtr.assign(nserror_object)
end
result
end

def writeToURL_ofType_forSaveOperation_originalContentsURL_error(url, type, op, content, errorPtr)

#-- if content is not nil, then we are saving a newly created document
#-- in this case, initWithURL is not called, so we had no chance to fix the url,
#-- let's do it here.
if (content nil)
path = url.relativePath
url = dataStoreURLFromPackageURL(url)
isDirectory = false
if (!OSX::NSFileManager.defaultManager.createDirectoryAtPath_attributes(path, nil))
#-- YOUR ERROR MANAGEMENT HERE, set errorPtr
return false
end
end

ok = super_writeToURL_ofType_forSaveOperation_originalContentsURL_error(url, type, op, content, nil)

if (!ok)
#-- SET ERROR INFORMATION TO BE RETURNED VIA errorPtr.assign(nserror_object)
end
ok
end

def initWithContentsOfURL_ofType_error(url, type, errPtr)
url = dataStoreURLFromPackageURL(url)
ok, err = super_initWithContentsOfURL_ofType_error(url, type, nil)
if (!ok)
#-- SET ERROR INFORMATION TO BE RETURNED VIA errorPtr.assign(nserror_object)
end
ok
end

end

For a more detailed discussion of the rationale behind this implementation, see my previous post.

You should then change your MyDocument class (the one produced by XCode templates) so that it derives from PersistentPackageDocument instead of NSPersistentDocument and it adds a dataStoreName method that returns the data store file name for that specific document. Here an example:


class MyDocument < PersistentPackageDocument

Nspersistentdocument Core Data Tutorial For Mac Os

def dataStoreName
'data.xml'
end

#-- default RubyCocoa implementation: managedObjectModel, setManagedObjectContext, windowNibName, etc.

end

Supporting Recent Documents

The PersistentPackageDocumentClass as given above is fully capable of dealing with package documents embedding a Core Data data store. Unfortunately, it alone cannot ensure that the Recent Documents menu is correctly handled in your application. To that aim, you need to override your NSDocumentControllernoteNewRecentDocumentURL method so that it does some juggling with the path that is stored with the recent document menus.

If your package document is enough rich, chances are that you are already subclassing NSDocumentController, so overriding noteNewRecentDocumentURL is a snap. Otherwise, here is a sample subclass:


class PersistentPackageDocumentController < OSX::NSDocumentController

def init
super_init
end

def packageURLFromDataStoreURL(url)
dataStoreName = currentDocument.dataStoreName
OSX::NSURL.fileURLWithPath(url.relativePath.gsub(/#{dataStoreName}$/, '))
end

def noteNewRecentDocumentURL(url)
if (currentDocument)
super_noteNewRecentDocumentURL(packageURLFromDataStoreURL(url))
end
end

end

As already mentioned, the key point is the method noteNewRecentDocumentURL, while packageURLFromDataStoreURL is just responsible for string manipulation. Note also that packageURLFromDataStoreURL accesses the current document to retrieve its dataStoreName and this forces to guard against the case when there is no current document. There are many alternative implementation of this behaviour, in particular you could define the method dataStoreName in the document controller class and let PersistentPackageDocument access it there. This approach has the adavantage that a “current” document controller is always there, but for presentation reasons it is not taken here.

Sublassing NSDocumentController has its own particularities. The easiest way to do it is in Interface Builder MainMenu.nib file. Just subclass and instantiate it in the nib and the above code will be used for your document shared controller. Read this FAQ for more information.

Nspersistentdocument core data tutorial for mac windows 10

Summing up

Nspersistentdocument Core Data Tutorial For Mac

The two classes defined above will allow you to easily integrate package documents in your Core Data application.

One final note: make sure you define your document classes as packages in your target properties.

Following the steps in 'Create a Custom Class' section, I added the Employee class, changed the Model Key Path, in the binding of contentValues of the manager pop-up menu, to fullNameAndID.
However, when built & go, the code snippet given above will cause a warning as described in the comment. The built is successful, with the compication that the pop-up menu doesn't update the fullNameAndID accordingly. I figured it could have something to do with the formatting string. So referenced relevant document, then found that '%@' could be used with any object. This led me to thought that maybe it's because that employeeID is defined as an integer 32 in the data model. Then I tried to change the last %@ to '%d', but the warning still showed up.
After all that, I'm stuck. So, could anyone help me out with this?!
Thank you very much!
--- Sherlock Asimov

12' Powerbook G4 M9691, Mac OS X (10.5)

Posted on Nov 4, 2007 11:29 PM