MTCoreData_AppDelegate.m and a Cancel button

Discussion in 'Mac Programming' started by Thom_Edwards, Oct 24, 2010.

  1. Thom_Edwards macrumors regular

    Apr 11, 2003
    I've diving in to Cocoa, coming from a php and ASP.Net (with C#) background. I'm making good headway, but I've hit a bump and need some help from you guys.

    First off, here is the code that is confusing me. Specifically, it's the last two ifs, which I detail later.
    - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
        if (!managedObjectContext) return NSTerminateNow;
        if (![managedObjectContext commitEditing]) {
            NSLog(@"%@:%s unable to commit editing to terminate", [self class], _cmd);
            return NSTerminateCancel;
        if (![managedObjectContext hasChanges]) return NSTerminateNow;
        NSError *error = nil;
        if (![managedObjectContext save:&error]) {
            // This error handling simply presents error information in a panel with an 
            // "Ok" button, which does not include any attempt at error recovery (meaning, 
            // attempting to fix the error.)  As a result, this implementation will 
            // present the information to the user and then follow up with a panel asking 
            // if the user wishes to "Quit Anyway", without saving the changes.
            // Typically, this process should be altered to include application-specific 
            // recovery steps.  
            BOOL result = [sender presentError:error];
            if (result) return NSTerminateCancel;
            NSString *question = NSLocalizedString(@"Could not save changes while quitting.  Quit anyway?", @"Quit without saves error question message");
            NSString *info = NSLocalizedString(@"Quitting now will lose any changes you have made since the last successful save", @"Quit without saves error question info");
            NSString *quitButton = NSLocalizedString(@"Quit anyway", @"Quit anyway button title");
            NSString *cancelButton = NSLocalizedString(@"Cancel", @"Cancel button title");
            NSAlert *alert = [[NSAlert alloc] init];
            [alert setMessageText:question];
            [alert setInformativeText:info];
            [alert addButtonWithTitle:quitButton];
            [alert addButtonWithTitle:cancelButton];
            NSInteger answer = [alert runModal];
            [alert release];
            alert = nil;
            if (answer == NSAlertAlternateReturn) return NSTerminateCancel; //doesn't work
    	if (answer == 1001) return NSTerminateCancel; //works		
        return NSTerminateNow;
    I started a Core Data Cocoa application in version 3.2.4 in Snow Leopard, set up my data model, laid out the interface, and set up the bindings. In the data model I have an entity with a property (namely isbn, this is a book catalog app) set with Optional off and no Default Value. Note that I have not changed one line of code--I'm just going with the code produced by Xcode. Build and Run, and away I go...

    Everything works great. I can add and delete records, edit them. I'm thinking, "Pretty Great! That wasn't too tough, and I've got a pretty slick, while simple, app going here!"

    Well, when I quit without the required ISBN, I get an alert saying it is required. Good. Next I get an alert, "Could not save changes while quitting..." with a Quit Anyway button and a Cancel button. Again, this is straight from the produced code and expected behavior. Still Good.

    But now is the problem. When I click Cancel, the app quits. (When I click Quit, it quits. I'm good with that.) One thing I notice is that if I leave the ISBN completely empty, I get this behavior. If I have an entry that does not meet the RegEx requirement, it gives me an option to Discard Changes, but it never gives me the Quit Anyway alert. Anyway, this line in makes me believe it should not quit when I click cancel.
    // answer is an NSInteger returned from [NSAlert runModal]
    if (answer == NSAlertAlternateReturn) return NSTerminateCancel;
    That returns false (or NO, I guess, in Objective-C). I see it happen in the debugger. Also, when I look in the debugger, it shows that answer is set to 1001. (Strangely, from what I can see NSTerminateCancel should be 0. Not sure where 1001 comes from, but that's not real important to me right now. Should it be?) I can change the if to say if (answer == 1001) and it works as I want it. But, I can't understand why it doesn't recognize NSAlertAlternateReturn as the Cancel click.

    Also, in the template code produced, there are the following comments:
    // Typically, this process should be altered to include application-specific 
    // recovery steps.
    I guess I'm at a loss as to what the correct "recovery steps" might be.

    Am I getting ahead of myself here? Am I digging too deep while still at an admittedly novice level? Maybe so, but it doesn't seem like this should be this confusing/difficult. I keep seeing things stating that when learning Cocoa you should let the framework do its job and not try to micro-manage things--I'm trying to keep that in mind.

    Sorry for the long post, and I hope it's not too confusing. I tried to explain my situation as best I can. Thanks for any and all help.

Share This Page