Mar*_*ino 0 macos cocoa core-data objective-c cocoa-bindings
我正在Cocoa中创建一个简单的基于文档的应用程序.此应用程序的每个文档基本上应该管理日期和注释的数组,因此每个记录都是日期和注释(textview).每个文档也受密码保护.
为此,我创建了一个名为HistoryElement的Core Data实体(包含日期和notes属性),我还创建了一个Settings实体,该实体应该只包含一个包含打开文件密码的记录(我没有找到更好的方法,有一个?密码绑定到每个文件,所以我不能使用首选项,因为它不是一个全局应用程序密码).
我有一个首选项选项卡,其中包含一个密码文本字段,该文本字段绑定到Settings实体的密码属性.
好的...现在的问题是:当我创建一个新文档时,Settings实体上没有记录,所以我希望以编程方式添加一个,这样用户就可以放入(如果要保护它的文件)密码密码文本字段.
相反,如果我打开现有文件,它应该发现已经添加了Settings实体的记录,并且它不应该再创建它,而是密码文本字段应该使用这个.
我尝试了很多方法,但我无法做到这一点.我试过这个例子:
if([[settingsArrayController arrangedObjects] count] == 0) {`
NSLog(@"Init settings");`
[settingsArrayController add:self];`
}
Run Code Online (Sandbox Code Playgroud)
它似乎在我创建新文档时添加了一条新记录,但如果我在密码文本字段中输入密码然后保存文档,当我再次打开文档时[[settingsArrayController arrangedObjects] count]返回0并再次创建新记录...
我怎样才能做到这一点 ?有一个更好/简单/优雅的方式来保护密码的文件?
在初始化managedObjectContext并加载数据后,您需要将代码添加到NSPersistentDocument.很难说你发布的示例代码有什么问题而不知道你把它放在哪里.
你可以放在一个简单的地方是在windowControllerDidLoadNib中.例如,
- (void)windowControllerDidLoadNib:(NSWindowController *)windowController
{
[super windowControllerDidLoadNib:windowController];
// user interface preparation code
NSManagedObjectContext *moc = [self managedObjectContext];
NSSet *settings = [moc fetchObjectsForEntityName:@"Settings"
withPredicate:nil];
if ([settings count] == 0)
{
NSManagedObject *obj = [NSEntityDescription insertNewObjectForEntityForName:@"Settings"
inManagedObjectContext:moc];
[obj setValue:@"myPass" forKey:@"password"];
} else {
// password record already exists, do something else.
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我在NSManagedObjectContext上使用了一个类别来执行所有样板查询:
// Convenience method to fetch the array of objects for a given Entity
// name in the context, optionally limiting by a predicate or by a predicate
// made from a format NSString and variable arguments.
//
- (NSSet *)fetchObjectsForEntityName:(NSString *)newEntityName
withPredicate:(id)stringOrPredicate, ...
{
NSEntityDescription *entity = [NSEntityDescription
entityForName:newEntityName inManagedObjectContext:self];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entity];
if (stringOrPredicate)
{
NSPredicate *predicate;
if ([stringOrPredicate isKindOfClass:[NSString class]])
{
va_list variadicArguments;
va_start(variadicArguments, stringOrPredicate);
predicate = [NSPredicate predicateWithFormat:stringOrPredicate
arguments:variadicArguments];
va_end(variadicArguments);
}
else
{
NSAssert2([stringOrPredicate isKindOfClass:[NSPredicate class]],
@"Second parameter passed to %s is of unexpected class %@",
sel_getName(_cmd), [stringOrPredicate className]);
predicate = (NSPredicate *)stringOrPredicate;
}
[request setPredicate:predicate];
}
NSError *error = nil;
NSArray *results = [self executeFetchRequest:request error:&error];
if (error != nil)
{
[NSException raise:NSGenericException format:@"%@",[error description]];
}
return [NSSet setWithArray:results];
}
Run Code Online (Sandbox Code Playgroud)
这应该就是它的全部内容.
我创建了一个快速示例项目,说明了您需要执行的操作:http://dl.dropbox.com/u/21359504/coredata-example.zip
| 归档时间: |
|
| 查看次数: |
2775 次 |
| 最近记录: |