+ entityForName: nil no es un parámetro legal de NSManagedObjectContext que busca el nombre de la entidad ‘Cuenta’

He intentado muchas opciones, pero no puedo encontrar la solución para este problema. Creé un archivo de Datos centrales y denominé la entidad Cuenta, Creé un atributo de cadena llamado nombre de usuario. Luego editó la clase de la entidad a NSManagedObject, no estoy seguro si esto es correcto. Ahora, el siguiente código está en mi LoginViewController:

- (void)viewDidLoad { [super viewDidLoad]; ITAppDelegate *appDelegate = (ITAppDelegate *)[[UIApplication sharedApplication] delegate]; NSManagedObjectContext *context = appDelegate.managedObjectContext; Account *newAccount = [NSEntityDescription insertNewObjectForEntityForName:@"Account" inManagedObjectContext:context]; [newAccount setValue:@"Jorge" forKey:@"username"]; [newAccount setPassword:@"password"]; NSLog(@"username:%@ password: %@", [newAccount username], [newAccount password]); } 

Seguí este tutorial y mis archivos de código se ven así:

ITAppDelegate.h

 #import  @interface ITAppDelegate : UIResponder  @property (strong, nonatomic) UIWindow *window; @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; @end 

ITAppDelegate.m

 #import "ITAppDelegate.h" #import "LoginViewController.h" @implementation ITAppDelegate @synthesize managedObjectContext = _managedObjectContext; @synthesize persistentStoreCoordinator = _persistentStoreCoordinator; @synthesize managedObjectModel = _managedObjectModel; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. return YES; } #pragma mark - Core Data stack - (NSManagedObjectContext *)managedObjectContext { if (_managedObjectContext != nil) { return _managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { _managedObjectContext = [[NSManagedObjectContext alloc] init]; [_managedObjectContext setPersistentStoreCoordinator:coordinator]; } return _managedObjectContext; } - (NSManagedObjectModel *)managedObjectModel { if (_managedObjectModel != nil) { return _managedObjectModel; } NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return _managedObjectModel; } - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (_persistentStoreCoordinator != nil) { return _persistentStoreCoordinator; } return _persistentStoreCoordinator; } @end 

AccountBase.h

 #import  #import  @interface AccountBase : NSManagedObject @property (nonatomic, retain) NSString *username; @end 

AccountBase.m

 #import "AccountBase.h" @implementation AccountBase @dynamic username; @end 

Cuenta.h

 #import "AccountBase.h" #import  @interface Account : AccountBase @property (nonatomic, assign) NSString *password; @end 

Cuenta.m

 #import "Account.h" #import "KeychainHelper.h" @implementation Account - (NSString*)password { if (self.username) return [KeychainHelper getPasswordForKey:self.username]; return nil; } - (void)setPassword:(NSString*)aPassword { if (self.username) [KeychainHelper setPassword:aPassword forKey:self.username]; } - (void)prepareForDeletion { if (self.username) [KeychainHelper removePasswordForKey:self.username]; } @end 

KeychainHelper.h

 #import  @interface KeychainHelper : NSObject + (NSString*)getPasswordForKey:(NSString*)aKey; + (void)setPassword:(NSString*)aPassword forKey:(NSString*)aKey; + (void)removePasswordForKey:(NSString*)aKey; @end 

KeychainHelper.m

 #import "KeychainHelper.h" #import  @interface KeychainHelper () + (NSMutableDictionary*)dictionaryForKey:(NSString*)aKey; @end @implementation KeychainHelper static const NSString *ironTrainers = @"com.domain.myapplication"; + (NSMutableDictionary*)dictionaryForKey:(NSString*)aKey { NSData *encodedKey = [aKey dataUsingEncoding:NSUTF8StringEncoding]; NSMutableDictionary *searchDictionary = [NSMutableDictionary dictionary]; [searchDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; [searchDictionary setObject:encodedKey forKey:(__bridge id)kSecAttrGeneric]; [searchDictionary setObject:encodedKey forKey:(__bridge id)kSecAttrAccount]; [searchDictionary setObject:ironTrainers forKey:(__bridge id)kSecAttrService]; return searchDictionary; } + (NSString*)getPasswordForKey:(NSString*)aKey { NSString *password = nil; NSMutableDictionary *searchDictionary = [self dictionaryForKey:aKey]; [searchDictionary setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; [searchDictionary setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; CFTypeRef result = NULL; BOOL statusCode = SecItemCopyMatching((__bridge CFDictionaryRef)searchDictionary, &result); if (statusCode == errSecSuccess) { NSData *resultData = CFBridgingRelease(result); password = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding]; } return (__bridge NSString *)(result); } + (void)removePasswordForKey:(NSString*)aKey { NSMutableDictionary *keyDictionary = [self dictionaryForKey:aKey]; SecItemDelete((__bridge CFDictionaryRef)keyDictionary); } + (void)setPassword:(NSString*)aPassword forKey:(NSString*)aKey { [KeychainHelper removePasswordForKey:aKey]; NSData *encodedPassword = [aPassword dataUsingEncoding:NSUTF8StringEncoding]; NSMutableDictionary *keyDictionary = [self dictionaryForKey:aKey]; [keyDictionary setObject:encodedPassword forKey:(__bridge id)kSecValueData]; SecItemAdd((__bridge CFDictionaryRef)keyDictionary, nil); } @end 

Cualquier ayuda apreciada. Gracias.

 - (NSManagedObjectContext *)managedObjectContext { if (managedObjectContext != nil) return managedObjectContext; NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { managedObjectContext = [[NSManagedObjectContext alloc] init]; [managedObjectContext setPersistentStoreCoordinator:coordinator]; } return managedObjectContext; } 
  • No ha proporcionado una implementación de carga diferida de persistentStoreCoordinator
  • entonces el coordinator siempre será nil
  • así que siempre regresarás nil de este método
  • lo que significa que siempre obtendrás el error anterior.

Para explicar el error:

+ entityForName: nil no es un parámetro legal de NSManagedObjectContext que busca el nombre de la entidad ‘Cuenta’

No es inmediatamente obvio al leerlo, pero esto significa que no es legal pasar por el contexto del objeto gestionado. En la primera lectura, parece que está haciendo entityForName:nil pero ese no es el caso.

Para solucionar el problema, deberá proporcionar un coordinador de tienda persistente válido. Tengo un pequeño artículo aquí que explica qué tan poco código necesita para configurar una stack de datos básicos, esto puede ayudarlo.

En mi caso, estoy usando contextos múltiples (padres / hijos) con diferentes tipos de concurrencia para mejorar el rendimiento. Tengo tres contextos:

  1. storeContext que es el único contexto cuyo persistentStoreCoordinator se ha establecido.
  2. viewContext cuyo elemento primario es storeContext
  3. backgroundContext cuyo padre debería haber sido viewContext pero olvidé establecer backgroundContext.parent = viewContext .

Guardar una entidad en el backgroundContext produjo el mismo error …

+ entityForName: nil no es un parámetro legal de NSManagedObjectContext que busca el nombre de la entidad …

… porque backgroundContext no era parte de la cadena de contexto padre / hijo.

viewContext establecer el viewContext parent de viewContext para viewContext restableció la cadena al coordinador de tienda persistente y se resolvió el error.

Encontré este error de entityForName: nil , pero terminó siendo algo así como una entityForName: nil falsa que solo se manifestó cuando ejecuté pruebas unitarias en mi CI. Durante las pruebas, la aplicación se encontró con algunas condiciones de subprocesamiento extrañas causadas por el importador HTML de NSAttributedString . Un envío asincrónico a la cola principal para interactuar con los datos principales estaba sucediendo justo cuando NSAttributedString se estaba creando desde HTML.

Solo publico mi experiencia aquí en caso de que termine ayudando a alguien más. 🙂

Puede suceder debido a la falta de coincidencia del nombre de la entidad y su nombre de clase. Asegúrese de que la entidad de su Cuenta tenga un nombre de clase apropiado en el archivo .xcdatamodeld.