我已经尝试了很多选项,但找不到此问题的解决方案.我创建了一个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,它解释了你需要多少代码来设置核心数据堆栈,这可能会帮助你.