Open a file with your own application written in objective-c

I would like to know how to open a file using my OS X application, which I wrote in Objective-C. I registered the file types in Info.plist and I have application:openFile: in my code. I did everything, this post , which was marked as resolved.

The problem is that this only works if I drag and drop my file into my application while it is running. But this does not work if I just double-clicked on the file. It launches my application, but not as it would be if I dragged. Thus, the code that is in application:openFile: does not run when you double-click, but only when you drag and drop the file.

EDIT:

More details about my code and what I'm trying to achieve. I created a wrapper application for another application. Let me call the other application "HelperApp.app". This HelperApp is located inside the /Contents/ folder of my shell application. In the wrapper application, I specified a new file type, let’s call it β€œ.ha” in the Info.plist file. This file contains some argument commands. What I'm trying to achieve when a user clicks on a file that is a ".ha" file, then my shell application reads in the argument from this file and sets it for HelperApp, and then launches HelperApp. This HelperApp opens up different things depending on the argument it receives. Below you can check my code.

I have AppDelegate.h and AppDelegate.mm by default, as the new Xcode creates it. I added this line to my AppDelegate.h , before "@end":

 - (BOOL)processFile:(NSString *)file; 

I have these functions in my AppDelegate.mm :

 #import "AppDelegate.h" #import "ArgumentParser.h" @implementation AppDelegate - (void)dealloc { [super dealloc]; } - (BOOL)application:(NSApplication *)WrapperApp openFile:(NSString *)filename { return [self processFile:filename]; } - (BOOL)processFile:(NSString *)file { NSLog(@"The following file has been dropped or selected: %@",file); std::string path = [file cStringUsingEncoding:[NSString defaultCStringEncoding]]; ArgumentParser parser = ArgumentParser(); parser.getArgumentfromFile(path); parser.setArgumentinFile(); // <== This is the "corrupted" function NSBundle *mainBundle = [NSBundle mainBundle]; NSString *helperAppPath = [[mainBundle bundlePath] stringByAppendingString:@"/Contents/HelperApp.app"]; [[NSWorkspace sharedWorkspace] launchApplication:helperAppPath]; return YES; } - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { // Insert code here to initialize your application } 

The corrupt function is setArgumentinFile() :

 void ArgumentParser::setArgumentinFile() { std::string content = ""; // The file content std::fstream file; file.open("HelperApp.app/Contents/Wrapper/HelperApp.app/Contents/Info.plist"); // Open the file and modify the arguments if(file.is_open()) { std::stringstream stream; stream << file.rdbuf(); std::string line = ""; bool isIt = false; while(getline(stream, line)) { // This line is the argument list, which needs to be modifyed if(isIt) { int index = (int)line.find_last_of("<"); std::string start = line.substr(0, index); std::string end = line.substr(index, std::string::npos); std::string argument_list = start + " " + _argument + end; content += argument_list + '\n'; isIt = false; } // Save the rest of the file so we can overwrite it else { content += line + '\n'; } // Next line is the argument list if(line.find("WineProgramArguments") != std::string::npos) { isIt = true; } } file.flush(); file.close(); } else { file.flush(); file.close(); throw std::runtime_error("File isn't opened"); } file.open("HelperApp.app/Contents/Wrapper/HelperApp.app/Contents/Info.plist", std::ios::out); // Open the file and overwrite it with the modifyed argument if(file.is_open()) { file << content; file.flush(); file.close(); } else { file.flush(); file.close(); throw std::runtime_error("File isn't opened"); } } 

If I comment on the above function from the processFile function in AppDelegate , then everything will work "smoothly". I mean, the wrapper application launches and launches HelperApp with default arguments. Therefore, there should be an error ...

+4
source share
4 answers

The problem was that I gave the wrong path in my function. This way worked if I started the application with Xcode, but did not if I started the application myself.

Here is the message that solved my problem!

0
source

If you implemented -application:openFile: it should be called when you double-click the file with the registered type. You say that the application is starting, so the OS is trying to use your application to open the file. Here is a helpful note from the documentation:

If the user starts the application by double-clicking the file, the delegate receives a request: openFile: message before receiving applicationDidFinishLaunching :. (applicationWillFinishLaunching: is sent before application: openFile :.)

So, if you are doing something in -applicationDidFinishLaunching: what you need to do before opening any files, this may be your problem. Consider porting your application initialization code to -applicationWillFinishLaunching:

+4
source

I get it. When you double-click the file icon, the application will start, others will execute correctly. But an application that responds to your actions is not necessarily the one you created the last time. The old copy of your application probably answers. Take a look at the library> Developer> Xcode> DrivedData. You should see many folders for your application. You can find application folders by right-clicking and selecting "Show in Finder" after the build. Destroy them all and create a new application. Then double-click and see what is happening now.

+1
source

right-click versus double-click to open the file in different ways!

Apple Docs:

If the user starts the application by double-clicking the file, the delegate will receive the application: openFile: message before receiving applicationDidFinishLaunching :. (applicationWillFinishLaunching: sent before the application: openFile :.)

Apple Docs does not contain important information ... I assumed that right-clicking β†’ β€œOpen with” operation in Finder would be the same as double-clicking. Its NOT!

application: openFile: happens AFTER applicationDidFinishLaunching: in this case!

Scratched my head for an hour on this.

+1
source

Source: https://habr.com/ru/post/1482313/


All Articles