Some Alert Functions Deprecated in OS X 10.10


#1

So it looks like the following two NSAlert functions have been deprecated in OS X 10.10… [color=#0080FF][size=85]beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:[/size][/color] and [color=#0080FF][size=85]alertWithMessageText:defaultButton:alternateButton:otherButton:informativeTextWithFormat:[/size][/color]. The first class method seemed easy enough to replace. According to the Apple documentation you just alloc and init an NSAlert and set its attributes. The only slight difficulty was figuring out the appropriate selectors to send to the new NSAlert instance for each attribute, and the change-up in return button codes.

The second instance method was quite a bit harder for me to figure out, as the replacement method provided by Apple contained some very strange looking syntax for the [color=#0080FF][size=85]completionHandler:[/size][/color] as the argument for this was listed as: [color=#0080FF][size=85](void (^)(NSModalResponse returnCode))handler[/size][/color]. After a lot of scratching of the head, searching the Apple docs, googling the Internet, and finally skipping ahead to Chapter 29… I finally figured out that this was the syntax for a “block”.

I have to say, once I learned the format, I really like the new methods better. They both seem cleaner to me, especially the second one requiring the use of the block. The block eliminates the need for a separate [color=#0080FF][size=85]alertEnded:[/size][/color] instance method, and keeps the return code localized.

For others that will run into these deprecated functions, and that might wish to try to follow current Apple practices, I have copied below the code I ended up with. It seems to work! :astonished: ** Spoiler Alert ** It includes my solution to the challenge problem. ** Spoiler Alert **

[code]- (IBAction)removeEmployee:(id)sender {
NSArray *selectedPeople = [employeeController selectedObjects];

// Replacement for alertWithMessageText:defaultButton:alternateButton:otherButton:informativeTextWithFormat:
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:@"Do you really want to remove these people?"];
[alert addButtonWithTitle:@"Remove"];
[alert addButtonWithTitle:@"Keep, No Raise"];
[alert addButtonWithTitle:@"Cancel"];
unsigned long count = [selectedPeople count];
if (count == 1) {
    [alert setInformativeText:@"1 person will be removed."];
} else {
    [alert setInformativeText:[NSString stringWithFormat:@"%lu people will be removed.", count]];
}

NSLog(@"Starting alert sheet");

// Replacement for beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:
[alert beginSheetModalForWindow:[tableView window] completionHandler:^(NSModalResponse returnCode) {
    NSLog(@"Alert sheet ended");
    if (returnCode == NSAlertFirstButtonReturn) {
        // The argument to remove: is ignored. The array controller will delete the selectedObjects.
        [employeeController remove:nil];
    } else if (returnCode == NSAlertSecondButtonReturn) {
        for (Person *employee in selectedPeople) {
            [employee setExpectedRaise:0.0];
        }
    }
}];

}[/code]