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

2

7

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

Waxwork answered 16/3, 2011 at 21:8 Comment(1)
Why don't you use NSDocument? Not flexible enough?Loella
N
16

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.
}
Nocturnal answered 16/3, 2011 at 21:15 Comment(6)
I added the proper extensions to CFBundleDocumentTypes (*.xml file) But i don't understand how to configure the delegates... At the time i got a "selectFile" and all of my code depend of the result of my selectFile... how can i work and configure with the selectFile AND the openFile (to allow drag&drop feature)... Thanks for your help!Waxwork
I added some additional info, this explains how to process both dropped and selected files with one piece of code.Nocturnal
@Nocturnal this works great. But how can I tweak the plist to accept any file type AND folders?Sulfathiazole
Found another thread that answered it: #4357120Sulfathiazole
Just an additional info: if you drop something on the icon while the app is NOT running, the "openFile.." methods will be called BEFORE "applicationDidFinishLaunching".Blamable
Great answer! May I ask for an update, cause some functions are deprecated since it was posted.Piranha
L
0

for a quick&dirty solution:

Cocoa: Drag and Drop any file type

Tested under Xcode Version 11.4 (11E146) catalina 10.15.4 (19E266)

Leucopenia answered 1/4, 2020 at 10:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.