Creating a window programmatically at program start


#1

I’m writing a simple app (neither Document-based nor using Core Data) that’s supposed to displays some static data in a Master-Detail view. The data is read from disk in the init method of the AppDelegate. A typical data file has about 90MB of data that needs to be parsed. This takes about 4 seconds on my machine. However, it might take longer on older machines, therefore I want to display a progress bar during this phase. I’ve created a NSWindow containing a NSProgressIndicator and connected both outlets to the App Delegate. However, the NSWindow is only displayed once the App runs into the applicationDidFinishLaunching method. At that stage, loading is already finished and I don’t need that a progress indicator anymore.
How do I create a NSWindow while I’m still in the init method of the main app, i.e. directly at programm start?

EDIT: I hacked together this piece of code that does what I need so far, although the window it produces looks ugly.

@implementation XaAppDelegate

-(id) init {
    self=[super init];

    NSRect aFrame=NSMakeRect(0,0,200,30);
    NSWindow *progressWindow;
    NSProgressIndicator *progressBar=[[NSProgressIndicator alloc] initWithFrame:aFrame];
    unsigned numberOfLines, index;
    
    progressWindow=[[NSWindow alloc] 
                   initWithContentRect:aFrame
                   styleMask:NSBorderlessWindowMask 
                   backing:NSBackingStoreBuffered 
                   defer:NO];
    [progressWindow center];
    [progressWindow setContentView:progressBar];
    [progressBar setIndeterminate:NO];
    [progressBar setMinValue:0.0];
    [progressBar setMaxValue:(double)stringLength]; // number of chars in the file
    [progressWindow makeKeyAndOrderFront:NSApp];

//now we're scanning through the text file line by line
   for (index = 0, numberOfLines = 0; index < stringLength; numberOfLines++) {
        aRange=[aptdat lineRangeForRange:NSMakeRange(index, 0)];
        aLine=[aptdat substringWithRange:aRange];
        index = NSMaxRange(aRange);
        
        theScanner=[NSScanner scannerWithString:aLine];
        [progressBar setDoubleValue:(double)index]; //set the progressbar to the index that we're currently at in the file
//....do some parsing... 
    }
    [progressWindow orderOut:NSApp];
    return self;
}

I just started programming so I’m sure there is a much better way, maybe by forcing the nib to load in init already. Maybe someone more experienced has an idea. Thanks for reading thus far.


#2

If you’d like to design your progress window in Interface Builder, have a look at Chapter 12, NIB Files and NSWindowController. This chapter describes how to load a window out of a XIB/NIB file.

Basically what you’re doing is about as good as you’re going to get, structure-wise, unless you want to read the file on a background thread (Chapter 34, Concurrency). However, believe me when I say that concurrency opens up a whole new can of worms, so if you’re new to programming I would save that until later.

Adam