我已经尝试了很多选项,但找不到此问题的解决方案.我创建了一个Core Data文件,并命名为实体Account,创建一个名为username的字符串属性.然后将实体的类编辑为NSManagedObject,不知道这是否正确.现在,我的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]); }
我跟着This Tutorial,我的代码文件如下所示:
ITAppDelegate.h
#import <UIKit/UIKit.h> @interface ITAppDelegate : UIResponder <UIApplicationDelegate> @property (strong,nonatomic) UIWindow *window; @property (readonly,strong,nonatomic) NSManagedObjectContext *managedObjectContext; @property (readonly,nonatomic) NSManagedObjectModel *managedObjectModel; @property (readonly,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 <UIKit/UIKit.h> #import <CoreData/CoreData.h> @interface AccountBase : NSManagedObject @property (nonatomic,retain) NSString *username; @end
AccountBase.m
#import "AccountBase.h" @implementation AccountBase @dynamic username; @end
Account.h
#import "AccountBase.h" #import <CoreData/CoreData.h> @interface Account : AccountBase @property (nonatomic,assign) NSString *password; @end
Account.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 <Foundation/Foundation.h> @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 <Security/Security.h> @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
任何帮助赞赏.谢谢.
解决方法
- (NSManagedObjectContext *)managedObjectContext { if (managedObjectContext != nil) return managedObjectContext; NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { managedObjectContext = [[NSManagedObjectContext alloc] init]; [managedObjectContext setPersistentStoreCoordinator:coordinator]; } return managedObjectContext; }
>你没有提供一个延迟加载的persistentStoreCoordinator实现
>所以协调员总是没有
所以你总是从这个方法返回零
这意味着你会总是得到上面的错误.
解释错误:
+entityForName: nil is not a legal NSManagedObjectContext parameter searching for entity name ‘Account’
阅读它不是很明显,但这意味着,对于托管对象上下文来说,这不是一个合法的东西.一读,看起来你正在做entityForName:nil,但事实并非如此.
要解决此问题,您需要提供一个有效的持久性存储协调器.我有一篇小文章here,它解释了你需要多少代码来设置核心数据堆栈,这可能会帮助你.