How do I create an import-only document type in Cocoa?

血红的双手。 提交于 2019-12-03 14:37:32

1. Declare the file types as Document Types

Within your Xcode project, add a Document Type for all the file formats your application supports. Set the Role of each type according to your application's abilities:

  • Mark read/write capable file types as Editor;
  • Mark import only file types as Viewer.

Set the Class to the document type you want to handle each file type. One document class can handle multiple file types.

In the example below, there are three file types declared: font-pestle, otf, and ttf. The first, font-pestle, is the native format of the application. This type has the role Editor.

The remaining two formats, otf and ttf, can be imported but not written by the application; thus they are marked as Viewer.

2. Additional file types in your NSDocument subclass

With the Document Types added, the application will automatically allow users to open files of the specified types.

You need to add file type handling code to your document class. In the ideal case, add the branching code to the readFromData:ofType:error: method:

- (BOOL)readFromData:(NSData*)someData ofType:(NSString*)typeName error:(NSError**)outError
{
    if ([NSWorkspace.sharedWorkspace type:@"eu.miln.font-pestle" conformsToType:typeName] == YES)
    {
        // read native format
    }
    else if ([NSWorkspace.sharedWorkspace type:@"public.opentype-font" conformsToType:typeName] == YES)
    {
        // read import only format

        // disassociate document from file; makes document "untitled"
        self.fileURL = nil;
        // associate with primary file type
        self.fileType = @"eu.miln.font-pestle";

    }
    else // ...

}

The self.fileURL = nil; is important. By setting fileURL to nil, you are saying the document is not associated with any on-disk file and should be treated as a new document.

To allow auto-saving, implement the NSDocument method autosavingFileType to return the primary file type.

Alex, thanks for your answer, but I found a way that I like a bit more:

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName
               error:(NSError **)outError
{
    *outError = nil;
    if ([typeName isEqualToString:@"SomeReadOnlyType"])
    {
        // .. (load data here)
        [self setFileURL:nil];

        return result;
    }
    else
    {
        // .. (do whatever you do for other documents here)
    }
}

This way it's still possible to use the document system provided by Cocoa instead fo rolling my own.

I've also documented the solution here: http://www.cocoadev.com/index.pl?CFBundleTypeRole a bit down the page.

I don't believe that import functionality is supported by default in Cocoa. When the user clicks the Open button in the open panel, the framework calls openDocumentWithContentsOfURL:display:error: on NSDocumentController. This is where the document system figures out what type of file you're opening and consults with the Info.plist file to figure out which NSDocument subclass to use to open the document.

You could subclass NSDocumentController and override the openDocumentWithContentsOfURL:display:error: method to intercept the file types that should be imported rather than opened. In your NSDocument subclass, write a new initializer with a name like initWithImportedContentsOfURL:type:error: (or something with a better name :-) ) to create a new untitled document and read in the contents of the imported file.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!