!!! Listings zum Artikel "Von einem Ende zum anderen" !!! von Karl Banke in iX 7/2012, S. 1444 !!! Listing 1: -(BOOL)validateBirthday:(id *)ioValue error:(NSError **)outError { if (*ioValue == nil) { // trap this in setNilValueForKey? new NSNumber with value 0? return YES; } else { NSDate *inputDate = *ioValue; NSDate *currentDate = [NSDate date]; if ([currentDate compare:inputDate] == NSOrderedAscending) { if (outError != NULL) { NSString *errorStr = NSLocalizedStringFromTable( @"Birthday must be in the past", @"Person", @"validation: birthday in past error"); NSDictionary *userInfoDict = [NSDictionary dictionaryWithObject:errorStr forKey:NSLocalizedDescriptionKey]; NSError *error = [[[NSError alloc] initWithDomain:@"PERSON_ERROR_DOMAIN" code:PERSON_INVALID_AGE_CODE userInfo:userInfoDict] autorelease]; *outError = error; } return NO; } else { return YES; } } } !!! Listing 2: - (BOOL)validateForInsert:(NSError **)error { BOOL propertiesValid = [super validateForInsert:error]; // could stop here if invalid BOOL consistencyValid = [self validateConsistency:error]; return (propertiesValid && consistencyValid); } - (BOOL)validateForUpdate:(NSError **)error { BOOL propertiesValid = [super validateForUpdate:error]; // could stop here if invalid BOOL consistencyValid = [self validateConsistency:error]; return (propertiesValid && consistencyValid); } - (BOOL)validateConsistency:(NSError **)error { BOOL valid = YES; NSString *country = [self country]; NSString *postcode = [self postcode]; if ((country != nil) && (postcode != nil) && [country isEqualToString:@"Deutschland"]) { if ([postcode length] != 5) { valid = NO; // don't create an error if none was requested if (error != NULL) { NSBundle *myBundle = [NSBundle bundleForClass:[self class]]; NSString *postcodeErrorString = [myBundle localizedStringForKey:@"InvalidGermanPostcodeError" value:@"German Postcode has five digits." table:@"AddressErrorStrings"]; NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; [userInfo setObject:postcodeErrorString forKey:NSLocalizedFailureReasonErrorKey]; [userInfo setObject:self forKey:NSValidationObjectErrorKey]; NSError *germanPostCodeError = [NSError errorWithDomain:@"Address" code:NSManagedObjectValidationError userInfo:userInfo]; // if there was no previous error, return the new error if (*error == nil) { *error = germanPostCodeError; } // if there was a previous error, combine it with the existing one else { *error = [self errorFromOriginalError:*error error:germanPostCodeError]; } } } } return valid; } - (NSError *)errorFromOriginalError:(NSError *)originalError error:(NSError *)secondError { NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; NSMutableArray *errors = [NSMutableArray arrayWithObject:secondError]; if ([originalError code] == NSValidationMultipleErrorsError) { [userInfo addEntriesFromDictionary:[originalError userInfo]]; [errors addObjectsFromArray:[userInfo objectForKey:NSDetailedErrorsKey]]; } else { [errors addObject:originalError]; } [userInfo setObject:errors forKey:NSDetailedErrorsKey]; return [NSError errorWithDomain:NSCocoaErrorDomain code:NSValidationMultipleErrorsError userInfo:userInfo]; } !!! Listing 3: - (IBAction) insertPerson:(id) sender { NSArray *selectedObjects = [[self personController] selectedObjects]; NSError *error = nil; BOOL validateResult = YES; if (selectedObjects != nil && [selectedObjects count] != 0) { Person *person = [selectedObjects objectAtIndex:0]; if ([person isInserted]) { validateResult = [person validateForUpdate:&error]; } else { validateResult = [person validateForInsert:&error]; } } if (validateResult == YES) { [[self personController] insert:sender]; } else { [self presentError:error modalForWindow:[self windowForSheet] delegate:nil didPresentSelector:nil contextInfo:nil]; } } !!! Listing 4: - (id)initWithType:(NSString *)typeName error:(NSError **)outError { id result = [super initWithType:typeName error:outError]; // The document has been created. Now populate the data NSManagedObjectContext *context = [self managedObjectContext]; NSManagedObject *nextSalutation = [NSEntityDescription insertNewObjectForEntityForName:@"Salutation" inManagedObjectContext:context]; [nextSalutation setShortDesc:@"Hr"]; [nextSalutation setLongDesc:@"Herr"]; nextSalutation = [NSEntityDescription insertNewObjectForEntityForName:@"Salutation" inManagedObjectContext:context]; // Weitere Anreden anlegen // ... return result; } !!! Listing 5: Fr Frau Hr Herr !!! Listing 6: - (id)init { self = [super init]; if (self) { // Add your subclass-specific initialization here. // If an error occurs here, send a [self release] message and return nil. NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"order" ascending:YES]; NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; [self setSalutationSorters:sortDescriptors]; } return self; } !!! Listing 7: NSManagedObject *nextAddressType = [NSEntityDescription insertNewObjectForEntityForName:@"AddressType" inManagedObjectContext:context]; [nextAddressType setEntry:@"Hausanschrift"]; nextAddressType = [NSEntityDescription insertNewObjectForEntityForName:@"AddressType" inManagedObjectContext:context]; [nextAddressType setEntry:@"Firmenanschrift"]; !!! Listing 8: - (void) setAddressTypeValue:(NSString *)value { if (value != nil && [value length] != 0) { if ([self addressType] == nil || [value isEqualToString:[[self addressType] entry]] == NO ) { NSManagedObjectContext *moc = [self managedObjectContext]; NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"AddressType" inManagedObjectContext:moc]; NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; [request setEntity:entityDescription]; // Set example predicate and sort NSPredicate *predicate = [NSPredicate predicateWithFormat: @"entry == %@", value]; [request setPredicate:predicate]; NSError *error = nil; NSArray *array = [moc executeFetchRequest:request error:&error]; if (array != nil && [array count] != 0) { [self setAddressType:[array objectAtIndex:0]]; } else { // Create a new object and insert NSManagedObject *nextAddressType = [NSEntityDescription insertNewObjectForEntityForName:@"AddressType" inManagedObjectContext:moc]; [nextAddressType setEntry:value]; [self setAddressType:nextAddressType]; } } } else { [self setAddressType: nil]; } } !!! Listing 9: NSManagedObjectContext* context = [self managedObjectContext]; NSString* storePath = [[NSBundle mainBundle] pathForResource:@"defaults" ofType:@"sqlite"]; NSString* prefix = @"file://"; NSURL* storeURL = [NSURL URLWithString:[prefix stringByAppendingString:storePath]]; NSDictionary* storeOptions = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSReadOnlyPersistentStoreOption, nil]; NSPersistentStore *globalStore = [[context persistentStoreCoordinator] addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:storeOptions error:outError]; !!! Listing 10: NSArray* keyArray = [NSArray arrayWithObjects:@"longDesc", @"shortDesc", @"order", @"natPerson", nil]; NSMutableDictionary *entityDictionaries = [NSMutableDictionary dictionary]; [self readEntityWithContext:context entityName:@"Salutation" globalStore:globalStore outError:outError keyArray:keyArray entityDictionaries:entityDictionaries]; !!! Listing 11: [[context persistentStoreCoordinator] removePersistentStore:globalStore error:outError]; NSArray *fetchedDictionaries; NSEnumerator *entities = [entityDictionaries keyEnumerator]; NSString *nextEntityName; while ((nextEntityName = [entities nextObject])) { fetchedDictionaries = [entityDictionaries objectForKey:nextEntityName]; [self createEntitiesFromDictionaries:context entityName:nextEntityName fetchedDictionaries:fetchedDictionaries]; }