Search code examples
objective-ccocoaxcodemacosnsdocument

Cocoa/Obj-C - Open file when dragging it to application icon


Currently there is a button on my app inteface which allow to open a file, here is my open code:

In my app.h:

- (IBAction)selectFile:(id)sender;

In my app.m:

@synthesize window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

}

- (IBAction)selectFile:(id)sender {

    NSOpenPanel *openPanel  = [NSOpenPanel openPanel];
    NSArray *fileTypes = [NSArray arrayWithObjects:@"xml",nil];

    NSInteger result  = [openPanel runModalForDirectory:NSHomeDirectory() file:nil types:fileTypes ];

    if(result == NSOKButton){

        NSString * input =  [openPanel filename];

How can I edit my code to allow opening with the application-icon drag & drop?
Note: I edited the .plist file and added a line for "xml" but it change anything, got an error when my file is dropped on the icon.
Note 2: I linked the "File -> Open..." to the selectFile: wich refer to my code
Note 3: My app isn't a document-based application


Thanks for your help!
Miskia


Solution

  • First add the proper extensions to CFBundleDocumentTypes inside the .plist file.

    Next implement the following delegates:
    - application:openFile: (one file dropped)
    - application:openFiles: (multiple files dropped)

    Reference:
    NSApplicationDelegate Protocol Reference

    Response to comment:

    Step by step example, hopefully it makes everything clear :)

    Add to the .plist file:

     <key>CFBundleDocumentTypes</key>
            <array>
                <dict>
                    <key>CFBundleTypeExtensions</key>
                    <array>
                        <string>xml</string>
                    </array>
                    <key>CFBundleTypeIconFile</key>
                    <string>application.icns</string>
                    <key>CFBundleTypeMIMETypes</key>
                    <array>
                        <string>text/xml</string>
                    </array>
                    <key>CFBundleTypeName</key>
                    <string>XML File</string>
                    <key>CFBundleTypeRole</key>
                    <string>Viewer</string>
                    <key>LSIsAppleDefaultForType</key>
                    <true/>
                </dict>
            </array>
    

    Add to ...AppDelegate.h

    - (BOOL)processFile:(NSString *)file;
    - (IBAction)openFileManually:(id)sender;
    

    Add to ...AppDelegate.m

    - (IBAction)openFileManually:(id)sender;
    {
        NSOpenPanel *openPanel  = [NSOpenPanel openPanel];
        NSArray *fileTypes = [NSArray arrayWithObjects:@"xml",nil];
        NSInteger result  = [openPanel runModalForDirectory:NSHomeDirectory() file:nil types:fileTypes ];
        if(result == NSOKButton){
            [self processFile:[openPanel filename]];
        }
    }
    
    - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
    {
        return [self processFile:filename];
    }
    
    - (BOOL)processFile:(NSString *)file
    {
        NSLog(@"The following file has been dropped or selected: %@",file);
        // Process file here
        return  YES; // Return YES when file processed succesfull, else return NO.
    }