A French solution for Challenge 28


#1

[code]//
// BNRDocument.m

#import “BNRDocument.h”

@implementation BNRDocument

  • (id)init
    {
    self = [super init];
    if (self) {
    // Add your subclass-specific initialization here.
    }
    return self;
    }

#pragma mark - Actions

  • (IBAction)creerNouvelleTache:(id)sender
    {
    // Si le tableau n’existe pas encore le créer
    if (!tachesAFaire) {
    tachesAFaire = [NSMutableArray array];
    }
    [tachesAFaire addObject:@“Nouvelle tache”];
    [tachesTableView reloadData];
    [self updateChangeCount:NSChangeDone];
    }

  • (IBAction)supprimerTache:(id)sender
    {
    if ([tachesTableView numberOfSelectedRows] == 0) {
    NSBeep();
    } else {
    [tachesAFaire removeObjectAtIndex:[tachesTableView selectedRow]];
    [tachesTableView reloadData];
    }
    }
    #pragma mark - Methode de la source de données

  • (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
    {
    return [tachesAFaire count];
    }

-(id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
return [tachesAFaire objectAtIndex:row];
}

  • (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
    {
    [tachesAFaire replaceObjectAtIndex:row withObject:object];
    [self updateChangeCount:NSChangeDone];
    }

  • (NSString *)windowNibName
    {
    // Override returning the nib file name of the document
    // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
    return @“BNRDocument”;
    }

  • (void)windowControllerDidLoadNib:(NSWindowController *)aController
    {
    [super windowControllerDidLoadNib:aController];
    // Add any code here that needs to be executed once the windowController has loaded the document’s window.
    }

  • (BOOL)autosavesInPlace
    {
    return YES;
    }
  • (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
    {
    if (!tachesAFaire) {
    tachesAFaire = [NSMutableArray array];
    }
    NSData *donnees = [NSPropertyListSerialization dataWithPropertyList:tachesAFaire
    format:NSPropertyListXMLFormat_v1_0
    options:NSPropertyListMutableContainers
    error];
    return donnees;
    }

  • (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError
    {
    tachesAFaire = [NSPropertyListSerialization propertyListWithData:data
    options:0
    format:NULL
    error];
    return (tachesAFaire != nil);
    }

@end
[/code]

I don’t understand the second challenge with NSError

Can somebody give me some hint(s) ?


#2

I think you are being asked to read the NSError Class Reference and to subclass NSError to create your own error classes in order to describe the specific reasons for failures.

Here is a hint:

//  main.m

#import <Foundation/Foundation.h>

@class Bar;
@interface FooBar: NSObject

- (id)initWithBar:(Bar *)bar error:(NSError **)reason;

@end

int main (int argc, const char * argv[])
{
    @autoreleasepool {
        FooBar *_1 = [[FooBar alloc] initWithBar:nil error:nil];
        if (!_1)
        {
            NSLog (@"_1: Error: Init failed!");
        }
        
        NSError *errorMsg = nil;
        FooBar *_2 = [[FooBar alloc] initWithBar:nil error:&errorMsg];
        if (!_2)
        {
            NSLog (@"_2: Error: Init failed!");
            if (errorMsg)
            {
                NSLog (@"_2: Error: reason: %@", [errorMsg localizedDescription]);
            }
        }
    }
    return 0;
}

@interface MyFooBarInitError : NSError

@end

@implementation FooBar

- (id)initWithBar:(Bar *)bar error:(NSError **)reason
{
    self = [super init];
    if (self)
    {
        // ...
        // initialization failed for some reason
        [self release];
        self = nil;
        
    }
    if (self == nil)
    {
        if (reason)
        {
            *reason = [[MyFooBarInitError alloc] init];
        }
    }
    return self;
}
@end

@implementation MyFooBarInitError

NSString  *const kMyInitErrorDomain = @"MyDomain";
NSUInteger const kMyInitErrorCode = 64;

- (id)init
{ 
    self = [super initWithDomain:kMyInitErrorDomain code:kMyInitErrorCode userInfo:nil];
    return self;
}

- (NSString *)localizedDescription
{
    return @"<Replace this with description of the reason for failure...>";
}

@end

The output:

2013-02-25 17:39:03.663 NSError[78726:403] _1: Error: Init failed!
2013-02-25 17:39:03.665 NSError[78726:403] _2: Error: Init failed!
2013-02-25 17:39:03.665 NSError[78726:403] _2: Error: reason: <Replace this with description of the reason for failure...>

#3

I block on the second part of the challenge too. I read the NSError Class Reference but I did not manage to really understand what is helpful to achieve this challenge. I’ve also read all topics linked to my problem, but I did not find the answers I expected.
What is really asked to do ? It is quite a vast question, I apologize about it, and any hints would be great.