0

I am experimenting with macOS xcode objective-C file handling - or having my app open files of a specific extension.

So far, I have used this doc to register file types (even though iOS and I'm using Mac, same process it seems) and that worked perfectly. That associates file extensions with my app and allows double-clicking of the files to launch my app.

Now I want to add handling of the file once it opens. I created a new Cocoa NSObject Subclass called FileOpen.

In my MainMenu.xib I created an Object (Blue Cube) and changed the class to FileOpen. I set it as delegate to File Owner. This was described in the selected answer to this stack question

Now, in FileOpen.m I have this - just to basically show a NSAlert when the file is opened:

- (void)applicationWillFinishLaunching:(NSNotification *)aNotification
{
NSLog(@"Application Finished Launching");
}

-(BOOL)application:(NSApplication*)sharedApplication openFile:(NSString*) fileName
{
[[NSAlert alertWithMessageText:@"Opening File"
defaultButton:@"OK"
alternateButton:nil
otherButton:nil
informativeTextWithFormat:@"Testing file opening handle code."] runModal];
return;
}

This all seems to work fine. If I run my app, I get the NSLog that the application finished launching. If I double-click a file, it runs the app and gives the NSAlert.

The problem I am running into is that my app has a splash screen. This shows until the user closes it and then the main app starts. If I disable my splash screen, the above all works fine as described. If I enable my splash screen, the NSLog saying application finished launching does run, after the splash screen, but then the application:openfile never runs (and no NSAlert).

I assume I need to add some code that waits for applicationWillFinishLaunching before running the application:open file? Is there a way to wait until the application is fully initialized to be able to open/handle the file correctly? It seems that by having a splash screen is interrupting the application:openfile

BinDev
  • 191
  • 13
  • Note that the application delegate method `applicationWillFinishLaunching` is called just _before_ the application object is initialized, while `applicationDidFinishLaunching` is called _after_ the application has been launched and initialized. – red_menace Oct 12 '20 at 21:28
  • Thank you for this red_menace - but this isn't really the issue. The issue I am having is application:openFile does not run if my app shows a splash screen first (a simple NSWindow). If I disable the splash screen, then it does run and displays the NSAlert - so the question is more: How can I wait until app fully starts (re: splash screen is closed and applicationWillFinishLaunching runs) to be able to open/handle the file correctly. It seems that by having a splash screen interrupts the application:openfile. – BinDev Oct 13 '20 at 13:29
  • 1
    Yes. You are blocking the app before it has a chance to finish launching. You might try showing your splash screen in `applicationDidFinishLaunching` (giving the app a chance to launch), stashing any files passed to `application:openFiles` (it is called after `applicationWillFinishLaunching`) in an instance variable until the dialog is complete. – red_menace Oct 13 '20 at 15:14

1 Answers1

0

Thanks to red_menace I was able to get this working. The key was moving the handling of my splash screen to the NSObject Subclass FileOpen. I did this by just adding a notification to open the splash screen in the FileOpen class instead of where it was originally invoked (the main view).

- (void)applicationWillFinishLaunching:(NSNotification *)aNotification
{
    NSLog(@"applicationWillFinishLaunching");
    [[NSNotificationCenter defaultCenter] postNotificationName:@"WhatsNewOpen" object:self];
}

-(BOOL)application:(NSApplication*)sharedApplication openFile:(NSString*) fileName
{
    
    [[NSAlert alertWithMessageText:@"Opening Files"
    defaultButton:@"OK"
    alternateButton:nil
    otherButton:nil
    informativeTextWithFormat:@"Testing File Open"] runModal];
    return;

}
BinDev
  • 191
  • 13