1

My application uses the following NSApplicationDelegate function.

- (void)application:(NSApplication*)sender openFiles:(NSArray*)filenames;

I want to use this function to enable the user to drag and drop image files onto the application icon in the dock.

How do I have to define certain file types in my plist file to restrict them to be images? I found out the structure has to look something like this.

// plist file contents taken from Preview.app
[...]
<key>CFBundleDocumentTypes</key>
<array>
    <dict>
        <key>CFBundleTypeIconFile</key>
        <string>jpeg.icns</string>
        <key>CFBundleTypeRole</key>
        <string>Viewer</string>
        <key>LSIsAppleDefaultForType</key>
        <true/>
        <key>LSItemContentTypes</key>
        <array>
            <string>public.jpeg</string>
        </array>
        <key>NSDocumentClass</key>
        <string>PVDocument</string>
    </dict>
</array>

I added it to the plist file but it does not work. A popup window shows the following error message.

The document "test.jpg" could not be opened. MyApp cannot open files in the "JPEG image" format.

Further, I read in the documentation that there is public.image which would be what I want to define.

Meanwhile, I found out that the plist file only contains the key CFBundleDocumentTypes if I create a Cocoa Application with the option "Create document-based application.". Can you please clarify what dependencies exist for the option?

JJD
  • 50,076
  • 60
  • 203
  • 339

2 Answers2

2
    <key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeExtensions</key>
            <array>
                <string>png</string>
                <string>jpg</string>
                            ... add as many types as you need
            </array>
                    ... other keys
        </dict>
    </array>

Update: The CFBundleDocumentTypes key is deprecated in Mac OS X v10.5. The new key LSItemContentTypes should be used instead. The items are UTI strings:

<key>LSItemContentTypes</key>
<array>
    <string>public.png</string>
</array>
Davyd Geyl
  • 4,578
  • 1
  • 28
  • 35
  • Two questions: (1) Are the types case-sensitive; in other words: do I need to add "PNG" and "JPG" and mixed variations as well? (2) Do you know why they do not use the UTI scheme (reverse DNS) here? – JJD Sep 06 '11 at 23:48
  • 1
    Sorry, the information was outdated. CFBundleDocumentTypes still works, but has been deprecated. (1) Is is case insensitive (2) See the update. – Davyd Geyl Sep 07 '11 at 02:42
  • Same error message. The `dict` element only contains `CFBundleTypeRole` and `CFBundleTypeExtensions` with values as suggested - but still it does not work. – JJD Sep 07 '11 at 09:26
  • Meanwhile, I created a new clean project and edited the plist as you suggest. It works. So the problem must be somewhere else .-( – JJD Sep 07 '11 at 11:10
  • The difference may be if MyApp is a document based application, but the new clean project is not. I see you use PVDocument class in you plist. In this case you do not need to implement [NSApplicationDelegate application: openFiles:], but [NSDocument readFromFileWrapper: ofType: error:] in your PVDocument subclass. – Davyd Geyl Sep 07 '11 at 11:35
  • No. The plist in my first post is taken from Preview.app - it was just an example. And yes - I left `NSDocumentClass` out. Secondly, my clean new test application is no document-based application. To repeat myself - this clean new test application works. But the real application does not. – JJD Sep 07 '11 at 12:21
  • I found the error somewhere else. I called a method in the `init`-method of an object. The method itself used self which has not been fully initialized in the middle of the `init`. - Thank you for you patience. I edited your post to add the full xml definition that works for me. - Interesting enough: `public.image` as a general definition does not work. – JJD Sep 07 '11 at 14:21
-1

If your document types are common types, you could use UTI's About UTI's

Tony
  • 4,311
  • 26
  • 49