Создадим новый проект:
Сделаем модель данных:
Простейшее правило валидации заключается в том чтобы сделать атрибут обязательным для заполнения и убрать для него значение по умолчанию:
Managed object context может быть создан по необходимости при первом вызове:
MyDocument.h
MyDocument.m
Сделаем модель данных:
Простейшее правило валидации заключается в том чтобы сделать атрибут обязательным для заполнения и убрать для него значение по умолчанию:
Managed object context может быть создан по необходимости при первом вызове:
MyDocument.h
#import <Cocoa/Cocoa.h> @interface MyDocument : NSPersistentDocument { NSManagedObject *customer; } - (NSManagedObject *)customer; - (void)setCustomer:(NSManagedObject *)aCustomer; @end
MyDocument.m
#import “Document.h” @implementation Document - (id)init { self = [super init]; if (self) { } return self; } - (id)initWithType:(NSString *)type error:(NSError **)error { self = [super initWithType:type error:error]; if (self != nil) { NSManagedObjectContext *managedObjectContext = [self managedObjectContext]; [self setCustomer:[NSEntityDescription insertNewObjectForEntity-ForName:@”Customer” inManagedObjectContext:managedObjectContext]]; } return self; } - (NSString *)windowNibName { return @”Document”; } - (void)windowControllerDidLoadNib:(NSWindowController *)aController { [super windowControllerDidLoadNib:aController]; } + (BOOL)autosavesInPlace { return NO; // see comment about testing } #pragma mark - Core Data stack - (NSManagedObject *)customer { if (customer != nil) { return customer; } NSManagedObjectContext *moc = [self managedObjectContext]; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSError *fetchError = nil; NSArray *fetchResults; @try { NSEntityDescription *entity = [NSEntityDescription entityForName:@”Customer” inManagedObjectContext:moc]; [fetchRequest setEntity:entity]; fetchResults = [moc executeFetchRequest:fetchRequest error:&fetchError]; } @finally { // for non-ARC projects, this would be [fetchRequest release]; } if ((fetchResults != nil) && ([fetchResults count] == 1) && (fetchError == nil)) { [self setCustomer:[fetchResults objectAtIndex:0]]; return customer; } if (fetchError != nil){ [self presentError:fetchError]; } else { // your own error message } return nil; } - (void)setCustomer:(NSManagedObject *)aCustomer { if (customer != aCustomer) { customer = aCustomer; } } @end
Создадим nib файл, добавим текстовые поля и object controller, который надо забиндить на managedObjectContext в File’s Owner.
Соедините биндинги из Customer controller с полями данных.
Надо выбрать поле данных, перейти в инспектор биндингов, и в секции Value привязать к Customer контроллеру. Controller Key надо установить в значение selection. Для Model Key Path нужно ввести наименование атрибута в модели данных.
При попытке сохранить неправильные данные будет появляться сообщение об ошибке:
Если ошибок несколько, то будет появляться общее сообщение:
Основой NSKeyValueCoding являются методы:
- (id)valueForKey:(NSString *)key - (void)setValue:(id)value forKey:(NSString *)key
Key-value валидация это API построенный на тех же концепциях, который позволяет валидировать значения свойств. Основной методы выполняющий валидацию:
Не нужно перекрывать метод validateValue:forKey:error. Он реализован в классе NSManagedObject. Если вы вызываете метод validateValue например для ключа price, то он ищет метод для валидации данного ключа, который будет следующим:
Вам не нужно вызывать этот метод самому.
NSManagedObject следующие методы которые можно перекрыть:
Пример:
- (BOOL)validateValue:(id *)ioValue forKey:(NSString *)key error:(NSError **)outError
Не нужно перекрывать метод validateValue:forKey:error. Он реализован в классе NSManagedObject. Если вы вызываете метод validateValue например для ключа price, то он ищет метод для валидации данного ключа, который будет следующим:
- (BOOL)validatePrice:(id *)ioValue error:(NSError **)outError
Вам не нужно вызывать этот метод самому.
NSError является прямым наследником NSObject. Основные свойства:
- code - NSInteger идентифицирующий ошибку;
- domain - NSString идентифицирующий область из которой вышла данная ошибка: NSMachErrorDomain, NSPOSIXErrorDomain, NSOSStatusErrorDomain, NSCocoaErrorDomain, com.yourorganization.yourapp.ErrorDomain
- userInfo - NSDictionary с деталями проблемы. Словарь содержит локализованные строки для следующих ключей: NSLocalizedDescriptionKey, NSErrorFailingURLStringKey, NSFilePathErrorKey, NSStringEncodingErrorKey, NSUnderlyingErrorKey, NSURLErrorKey, NSLocalizedFailureReasonErrorKey, NSLocalizedRecoverySuggestionErrorKey, NSLocalizedRecoveryOptionsErrorKey, NSRecoveryAttempterErrorKey, NSHelpAnchorErrorKey, NSURLErrorFailingURLErrorKey, NSURLErrorFailingURLStringErrorKey, NSURLErrorFailingURLPeerTrustErrorKey. Если нужно ключа нет, то используется ключ NSUnderlyingErrorKey.
NSManagedObject следующие методы которые можно перекрыть:
- (BOOL)validateForInsert:(NSError **)error - (BOOL)validateForDelete:(NSError **)error - (BOOL)validateForUpdate:(NSError **)error
Пример:
- (BOOL)validateForUpdate:(NSError **)error { [super validateForUpdate: error]; // your quality edit }