I'm trying to modernize a 20+ year old cocoa/objective-c application. It is document-based and it can read/write its own data to file, but the user can also choose saveAs… to export the document in standard formats (not read by the app).
From the (somewhat confusing) documentation I got the impression that an accessory panel shouldn't be needed to achieve this, given the correct information in Info.plist
.
I was expecting the user to pick a file format in the save panel and that that selection would be passed as the type when -dataOfType:error:
is invoked. However, type is always the document's native type, regardless of the choice in the save panel.
I'm trying this out on a toy project with a vanilla document based project with the following changes:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Default</string>
<key>LSItemContentTypes</key>
<array>
<string>net.sourceforge.foo</string>
</array>
<key>NSDocumentClass</key>
<string>Document</string>
</dict>
</array>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeIcons</key>
<dict/>
<key>UTTypeIdentifier</key>
<string>net.sourceforge.foo</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>foo</string>
</array>
</dict>
</dict>
</array>
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.plain-text</string>
</array>
<key>UTTypeDescription</key>
<string>Example Text</string>
<key>UTTypeIdentifier</key>
<string>com.example.plain-text</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>exampletext</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>net.daringfireball.markdown</string>
</array>
<key>UTTypeIcons</key>
<dict/>
<key>UTTypeIdentifier</key>
<string>com.example.mrkdwn</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>mrkdwn</string>
</array>
</dict>
</dict>
</array>
</dict>
</plist>
+ (BOOL)autosavesInPlace {
return NO;
}
+ (NSArray *)writableTypes {
return @[
@"net.sourceforge.foo",
@"com.example.plain-text",
@"com.example.mrkdwn",
@"net.daringfireball.markdown"
];
}
- (BOOL) prepareSavePanel:(NSSavePanel *) savePanel {
savePanel.allowedContentTypes = @[
[UTType typeWithIdentifier:@"com.example.plain-text"],
[UTType typeWithIdentifier:@"net.sourceforge.foo"],
[UTType typeWithIdentifier:@"com.example.mrkdwn"],
];
savePanel.showsContentTypes = YES;
return true;
}
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
NSLog(@"typeName: %@", typeName);
return nil;
}
Obviously I'm doing something wrong. Either I´m interpreting the docs wrong (and this approach is totally insane) or there is something not quite right in the Info.plist
and/or the code. Any hints to what is going on here would be much appreciated.
Here's how to implement Export in the vanilla document based project:
Add the imported file types (with a description) to info.plist
Implement writableTypes
Add a menu item "Export…" and connect it to the First Responder and action saveDocumentTo:
I vaguely remember reading documentation about this somewhere, but I can't find it anymore.