JSON 到核心数据中通过 UITableVewController 显示
NSManagedObjectModel 由以下部分组成:
#import <CoreData/CoreData.h>
@interface Event : NSManagedObject
{
}
@property (nonatomic, retain) NSString * summary;
@property (nonatomic, retain) NSString * content;
@property (nonatomic, retain) NSDate * updated;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSDate * created;
@property (nonatomic, retain) NSString * ID;
@end
我正在做的就是尝试将解析后的 JSON 插入到上述核心数据属性中。
在下文中,newNote 是我为 NSManagedObject 指定的名称。基本上我想要完成的是将 JSON 插入到核心数据中,以便我可以在 UITableView 中显示它。以下函数解析 JSON 并将其插入到 Core Data 中。
-(void)pullNotes {
UIApplication *app = [UIApplication alloc];
app.networkActivityIndicatorVisible = YES;
NSDictionary *params = [NSDictionary dictionaryWithObject:api_key forKey:@"api_key"];
[[LRResty client] get:@"http://notacio.us/api/note" parameters:params withBlock:^(LRRestyResponse *response){
if(response.status == 200) {
NSLog(@"Pulling the users notes \n%@", [response asString]);
// Create SBJSON object to parse JSON
SBJSON *parser = [[SBJSON alloc] init];
// parse the JSON string into an object - assuming [response asString] is a NSString of JSON data
NSDictionary *object = [parser objectWithString:[response asString] error:nil];
NSArray *notes = [object valueForKey:@"result"];
for (NSDictionary *singleNote in notes){
// newNote.created = [singleNote objectForKey:@"note created"]; Need to work on parsing these properly...
// newNote.updated = [singleNote objectForKey:@"note updated"]; Need to work on parsing these properly...
NSString *notetitle = [singleNote objectForKey:@"note title"];
NSString *notesummary = [singleNote objectForKey:@"note summary"];
NSString *noteid = [singleNote objectForKey:@"note id"];
NSString *notecontent = [singleNote objectForKey:@"note content"];
NSLog(@"Note Title: %@",notetitle);
NSLog(@"Note Summary: %@",notesummary);
NSLog(@"Note ID: %@",noteid);
NSLog(@"Note Content: %@",notecontent);
[newNote setValue:notecontent forKey:@"content"];
NSError *error = nil;
if (![newNote.managedObjectContext save:&error]) {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
*/
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
NSLog(@"Added Core Data Value: %@",[newNote valueForKey:@"content"]);
// NSDate *createdDate =
// NSDate *updatedDate =
[tableView reloadData];
app.networkActivityIndicatorVisible = NO;
}
}
if (response.status == 404) {
NSLog(@"FAIL\n%@", [response asString]);
app.networkActivityIndicatorVisible = NO;
}
}];
}
字符串的 NSLogs 返回正确的内容,所以我知道它实际上应该将它们插入到核心数据中......
所以,我的问题。
当该函数被调用时,我收到以下错误。
2011-02-26 21:37:30.797 Notacious[22570:207] Unresolved error (null), (null)
我不明白发生了什么,希望有人能够阐明我的问题。
编辑
经过几个小时的使用,我已经有了一些功能:
-(void)pullNotes {
UIApplication *app = [UIApplication alloc];
app.networkActivityIndicatorVisible = YES;
NSDictionary *params = [NSDictionary dictionaryWithObject:api_key forKey:@"api_key"];
[[LRResty client] get:@"http://notacio.us/api/note" parameters:params withBlock:^(LRRestyResponse *response){
if(response.status == 200) {
NSLog(@"Pulling the users notes \n%@", [response asString]);
// Create SBJSON object to parse JSON
SBJSON *parser = [[SBJSON alloc] init];
// parse the JSON string into an object - assuming [response asString] is a NSString of JSON data
NSDictionary *object = [parser objectWithString:[response asString] error:nil];
appDelegate =(NotaciousAppDelegate *) [[UIApplication sharedApplication] delegate];
NSManagedObject *newNote;
NSArray *notes = [object valueForKey:@"result"];
for (NSDictionary *singleNote in notes){
// newNote.created = [singleNote objectForKey:@"note created"]; Need to work on parsing these properly...
// newNote.updated = [singleNote objectForKey:@"note updated"]; Need to work on parsing these properly...
NSString *notetitle = [singleNote objectForKey:@"note title"];
NSString *notesummary = [singleNote objectForKey:@"note summary"];
NSString *noteid = [singleNote objectForKey:@"note id"];
NSString *notecontent = [singleNote objectForKey:@"note content"];
NSLog(@"Note Title: %@",notetitle);
NSLog(@"Note Summary: %@",notesummary);
NSLog(@"Note ID: %@",noteid);
NSLog(@"Note Content: %@",notecontent);
newNote = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:appDelegate.managedObjectContext];
[newNote setValue:notecontent forKey:@"content"];
[newNote setValue:notesummary forKey:@"summary"];
[newNote setValue:notetitle forKey:@"title"];
[newNote setValue:noteid forKey:@"ID"];
NSLog(@"Added Core Data Value: %@",[newNote valueForKey:@"content"]);
// NSDate *createdDate =
// NSDate *updatedDate =
app.networkActivityIndicatorVisible = NO;
}
NSError *error = nil;
if (![appDelegate.managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
if (response.status == 404) {
NSLog(@"FAIL\n%@", [response asString]);
app.networkActivityIndicatorVisible = NO;
}
}];
}
但是,它会添加实体,无论它们之前是否存在。我想要它做的是找到如果注释已经存在,则更新它。如果没有,请创建一个新的。
编辑
目前该函数现在看起来像这样:
-(void)pullNotes {
UIApplication *app = [UIApplication alloc];
app.networkActivityIndicatorVisible = YES;
NSDictionary *params = [NSDictionary dictionaryWithObject:api_key forKey:@"api_key"];
[[LRResty client] get:@"http://notacio.us/api/note" parameters:params withBlock:^(LRRestyResponse *response){
if(response.status == 200) {
NSLog(@"Pulling the users notes \n%@", [response asString]);
// Create SBJSON object to parse JSON
SBJSON *parser = [[SBJSON alloc] init];
// parse the JSON string into an object - assuming [response asString] is a NSString of JSON data
NSDictionary *object = [parser objectWithString:[response asString] error:nil];
appDelegate =(NotaciousAppDelegate *) [[UIApplication sharedApplication] delegate];
NSManagedObject *newNote;
NSEntityDescription *noteEntity=[NSEntityDescription entityForName:@"Event" inManagedObjectContext:appDelegate.managedObjectContext];
NSFetchRequest *noteFetch;
NSArray *fetchedNotes;
NSArray *notes = [object valueForKey:@"result"];
for (NSDictionary *singleNote in notes){
noteFetch=[[NSFetchRequest alloc] init];
[noteFetch setEntity:noteEntity];
NSPredicate *pred=[NSPredicate predicateWithFormat:@"noteID==%@",[singleNote objectForKey:@"note id"]];
[noteFetch setPredicate:pred];
NSError *fetchError=nil;
fetchedNotes=[appDelegate.managedObjectContext performFetch:&fetchError];
if (fetchError!=nil) {
NSLog(@"pullNotes fetchError=%@,details=%@",fetchError,fetchError.userInfo);
}
if ([fetchedNotes count]==0) {
// newNote.created = [singleNote objectForKey:@"note created"]; Need to work on parsing these properly...
// newNote.updated = [singleNote objectForKey:@"note updated"]; Need to work on parsing these properly...
NSString *notetitle = [singleNote objectForKey:@"note title"];
NSString *notesummary = [singleNote objectForKey:@"note summary"];
NSString *noteid = [singleNote objectForKey:@"note id"];
NSString *notecontent = [singleNote objectForKey:@"note content"];
NSLog(@"Note Title: %@",notetitle);
NSLog(@"Note Summary: %@",notesummary);
NSLog(@"Note ID: %@",noteid);
NSLog(@"Note Content: %@",notecontent);
newNote = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:appDelegate.managedObjectContext];
[newNote setValue:notecontent forKey:@"content"];
[newNote setValue:notesummary forKey:@"summary"];
[newNote setValue:notetitle forKey:@"title"];
[newNote setValue:noteid forKey:@"ID"];
// NSDate *createdDate =
// NSDate *updatedDate =
NSError *error = nil;
if (![appDelegate.managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
[noteFetch release];
app.networkActivityIndicatorVisible = NO;
}
}
if (response.status == 404) {
NSLog(@"FAIL\n%@", [response asString]);
app.networkActivityIndicatorVisible = NO;
}
}];
}
但是,在调用 appDelegate.managedObjectContext
时,我似乎遇到了错误,并且它只是出错了说以下内容:
2011-03-03 12:11:01.616 Notacious[182:307] -[NSManagedObjectContext performFetch:]: unrecognized selector sent to instance 0x1474e0
2011-03-03 12:11:01.781 Notacious[182:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSManagedObjectContext performFetch:]: unrecognized selector sent to instance 0x1474e0'
我已经尝试将其设置为 appDelegate.managedObjectContext_
但为了有效,它似乎返回一个错误,指出在 appDelegate 中找不到它并且它不是 getter 对象。然而,它在这里被明确分配: http://cl.ly/4xdX
EDIT
我想我最好编辑此内容以添加我当前的工作以及原始标题下的另一个问题。以下代码是我构建的并且工作得很好(除了编辑的字符串没有被保存,进而导致我的以下问题此处)。
-(void)syncNotes {
UIApplication *app = [UIApplication alloc];
app.networkActivityIndicatorVisible = YES;
NSDictionary *params = [NSDictionary dictionaryWithObject:authToken forKey:@"api_key"];
[[LRResty client] get:@"http://notacio.us/api/note" parameters:params withBlock:^(LRRestyResponse *response){
if(response.status == 200) {
// NSLog(@"Successful Connection \n%@", [response asString]);
// Create SBJSON object to parse JSON
SBJSON *parser = [[SBJSON alloc] init];
// parse the JSON string into an object - assuming [response asString] is a NSString of JSON data
NSDictionary *object = [parser objectWithString:[response asString] error:nil];
[parser release];
NSFetchRequest *noteFetch;
NSManagedObject *newNote;
appDelegate =(NotaciousAppDelegate *) [[UIApplication sharedApplication] delegate];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Note" inManagedObjectContext:appDelegate.managedObjectContext];
NSArray *fetchedNotes;
NSArray *notes = [object valueForKey:@"result"];
for (NSDictionary *singleNote in notes){
noteFetch=[[NSFetchRequest alloc] init];
[noteFetch setEntity:entity];
NSPredicate *pred=[NSPredicate predicateWithFormat:@"ID==%@",[singleNote objectForKey:@"note id"]];
[noteFetch setPredicate:pred];
NSError *fetchError=nil;
fetchedNotes=[appDelegate.managedObjectContext executeFetchRequest:noteFetch error:&fetchError];
if (fetchError!=nil) {
NSLog(@"syncNotes fetchError=%@,details=%@",fetchError,fetchError.userInfo);
}
if ([fetchedNotes count]==0) {
NSString *notelocked = [singleNote objectForKey:@"note locked"];
NSString *notecreated = [singleNote objectForKey:@"note created"];
NSString *noteupdated = [singleNote objectForKey:@"note updated"];
NSString *notetitle = [singleNote objectForKey:@"note title"];
NSString *notesummary = [singleNote objectForKey:@"note summary"];
NSString *noteid = [singleNote objectForKey:@"note id"];
NSString *notecontent = [singleNote objectForKey:@"note content"];
NSString *formattedTitle = [NSString decodeShit:notetitle];
NSString *formattedSummary = [NSString decodeShit:notesummary];
NSString *formattedContent = [NSString decodeShit:notecontent];
NSLog(@"Note Title: %@",formattedTitle);
NSLog(@"Note Summary: %@",formattedSummary);
NSLog(@"Note ID: %@",noteid);
NSLog(@"Note Content: %@",formattedContent);
NSLog(@"Note Created: %@",notecreated);
NSLog(@"Note Updated: %@",noteupdated);
NSLog(@"Note Locked: %@",notelocked);
newNote = [NSEntityDescription insertNewObjectForEntityForName:@"Note" inManagedObjectContext:appDelegate.managedObjectContext];
[newNote setValue:formattedContent forKey:@"content"];
[newNote setValue:formattedSummary forKey:@"summary"];
[newNote setValue:formattedTitle forKey:@"title"];
[newNote setValue:noteid forKey:@"ID"];
[newNote setValue:notecreated forKey:@"created"];
[newNote setValue:noteupdated forKey:@"updated"];
[newNote setValue:notelocked forKey:@"locked"];
NSError *error = nil;
if (![appDelegate.managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
[noteFetch release];
}
app.networkActivityIndicatorVisible = NO;
}
if (response.status == 404) {
NSLog(@"FAIL\n%@", [response asString]);
app.networkActivityIndicatorVisible = NO;
}
}];
}
现在,这确实有效,但是当内容字符串不同时,我想更新正确的注释。这里有人愿意详细说明如何做到这一点吗?
我知道我一直在这里问问题,但想让一切变得完美,而且似乎我对这种简单任务的了解有些不存在。任何意见将不胜感激!
编辑
啊,另一个请求。如果当前存储的笔记没有 noteID,那么是否将其从核心数据中删除?这可能吗?
The NSManagedObjectModel consists of the following:
#import <CoreData/CoreData.h>
@interface Event : NSManagedObject
{
}
@property (nonatomic, retain) NSString * summary;
@property (nonatomic, retain) NSString * content;
@property (nonatomic, retain) NSDate * updated;
@property (nonatomic, retain) NSString * title;
@property (nonatomic, retain) NSDate * created;
@property (nonatomic, retain) NSString * ID;
@end
What I'm doing is trying to insert parsed JSON into the above Core Data attributes.
In the following, newNote is the name I have given to the NSManagedObject. Basically what I'm trying to accomplish is inserting the JSON into the Core Data so that I can then display it in a UITableView. The following function is what parses the JSON and inserts it into Core Data.
-(void)pullNotes {
UIApplication *app = [UIApplication alloc];
app.networkActivityIndicatorVisible = YES;
NSDictionary *params = [NSDictionary dictionaryWithObject:api_key forKey:@"api_key"];
[[LRResty client] get:@"http://notacio.us/api/note" parameters:params withBlock:^(LRRestyResponse *response){
if(response.status == 200) {
NSLog(@"Pulling the users notes \n%@", [response asString]);
// Create SBJSON object to parse JSON
SBJSON *parser = [[SBJSON alloc] init];
// parse the JSON string into an object - assuming [response asString] is a NSString of JSON data
NSDictionary *object = [parser objectWithString:[response asString] error:nil];
NSArray *notes = [object valueForKey:@"result"];
for (NSDictionary *singleNote in notes){
// newNote.created = [singleNote objectForKey:@"note created"]; Need to work on parsing these properly...
// newNote.updated = [singleNote objectForKey:@"note updated"]; Need to work on parsing these properly...
NSString *notetitle = [singleNote objectForKey:@"note title"];
NSString *notesummary = [singleNote objectForKey:@"note summary"];
NSString *noteid = [singleNote objectForKey:@"note id"];
NSString *notecontent = [singleNote objectForKey:@"note content"];
NSLog(@"Note Title: %@",notetitle);
NSLog(@"Note Summary: %@",notesummary);
NSLog(@"Note ID: %@",noteid);
NSLog(@"Note Content: %@",notecontent);
[newNote setValue:notecontent forKey:@"content"];
NSError *error = nil;
if (![newNote.managedObjectContext save:&error]) {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
*/
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
NSLog(@"Added Core Data Value: %@",[newNote valueForKey:@"content"]);
// NSDate *createdDate =
// NSDate *updatedDate =
[tableView reloadData];
app.networkActivityIndicatorVisible = NO;
}
}
if (response.status == 404) {
NSLog(@"FAIL\n%@", [response asString]);
app.networkActivityIndicatorVisible = NO;
}
}];
}
The NSLogs of the strings are returning the correct things, so I know that it should actually be inserting them into the Core Data...
So, my issue.
When that function gets called I get the following error.
2011-02-26 21:37:30.797 Notacious[22570:207] Unresolved error (null), (null)
I don't understand what is happening and hopefully someone will be able to shed some light on my issue.
EDIT
After a few hours of playing with it, I have it somewhat functioning:
-(void)pullNotes {
UIApplication *app = [UIApplication alloc];
app.networkActivityIndicatorVisible = YES;
NSDictionary *params = [NSDictionary dictionaryWithObject:api_key forKey:@"api_key"];
[[LRResty client] get:@"http://notacio.us/api/note" parameters:params withBlock:^(LRRestyResponse *response){
if(response.status == 200) {
NSLog(@"Pulling the users notes \n%@", [response asString]);
// Create SBJSON object to parse JSON
SBJSON *parser = [[SBJSON alloc] init];
// parse the JSON string into an object - assuming [response asString] is a NSString of JSON data
NSDictionary *object = [parser objectWithString:[response asString] error:nil];
appDelegate =(NotaciousAppDelegate *) [[UIApplication sharedApplication] delegate];
NSManagedObject *newNote;
NSArray *notes = [object valueForKey:@"result"];
for (NSDictionary *singleNote in notes){
// newNote.created = [singleNote objectForKey:@"note created"]; Need to work on parsing these properly...
// newNote.updated = [singleNote objectForKey:@"note updated"]; Need to work on parsing these properly...
NSString *notetitle = [singleNote objectForKey:@"note title"];
NSString *notesummary = [singleNote objectForKey:@"note summary"];
NSString *noteid = [singleNote objectForKey:@"note id"];
NSString *notecontent = [singleNote objectForKey:@"note content"];
NSLog(@"Note Title: %@",notetitle);
NSLog(@"Note Summary: %@",notesummary);
NSLog(@"Note ID: %@",noteid);
NSLog(@"Note Content: %@",notecontent);
newNote = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:appDelegate.managedObjectContext];
[newNote setValue:notecontent forKey:@"content"];
[newNote setValue:notesummary forKey:@"summary"];
[newNote setValue:notetitle forKey:@"title"];
[newNote setValue:noteid forKey:@"ID"];
NSLog(@"Added Core Data Value: %@",[newNote valueForKey:@"content"]);
// NSDate *createdDate =
// NSDate *updatedDate =
app.networkActivityIndicatorVisible = NO;
}
NSError *error = nil;
if (![appDelegate.managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
if (response.status == 404) {
NSLog(@"FAIL\n%@", [response asString]);
app.networkActivityIndicatorVisible = NO;
}
}];
}
However, it adds entities regardless of whether or not they were there before. What I want it to do is to find that if a note is already there, update it. If not, create a new one.
EDIT
Currently the function is now looking like this:
-(void)pullNotes {
UIApplication *app = [UIApplication alloc];
app.networkActivityIndicatorVisible = YES;
NSDictionary *params = [NSDictionary dictionaryWithObject:api_key forKey:@"api_key"];
[[LRResty client] get:@"http://notacio.us/api/note" parameters:params withBlock:^(LRRestyResponse *response){
if(response.status == 200) {
NSLog(@"Pulling the users notes \n%@", [response asString]);
// Create SBJSON object to parse JSON
SBJSON *parser = [[SBJSON alloc] init];
// parse the JSON string into an object - assuming [response asString] is a NSString of JSON data
NSDictionary *object = [parser objectWithString:[response asString] error:nil];
appDelegate =(NotaciousAppDelegate *) [[UIApplication sharedApplication] delegate];
NSManagedObject *newNote;
NSEntityDescription *noteEntity=[NSEntityDescription entityForName:@"Event" inManagedObjectContext:appDelegate.managedObjectContext];
NSFetchRequest *noteFetch;
NSArray *fetchedNotes;
NSArray *notes = [object valueForKey:@"result"];
for (NSDictionary *singleNote in notes){
noteFetch=[[NSFetchRequest alloc] init];
[noteFetch setEntity:noteEntity];
NSPredicate *pred=[NSPredicate predicateWithFormat:@"noteID==%@",[singleNote objectForKey:@"note id"]];
[noteFetch setPredicate:pred];
NSError *fetchError=nil;
fetchedNotes=[appDelegate.managedObjectContext performFetch:&fetchError];
if (fetchError!=nil) {
NSLog(@"pullNotes fetchError=%@,details=%@",fetchError,fetchError.userInfo);
}
if ([fetchedNotes count]==0) {
// newNote.created = [singleNote objectForKey:@"note created"]; Need to work on parsing these properly...
// newNote.updated = [singleNote objectForKey:@"note updated"]; Need to work on parsing these properly...
NSString *notetitle = [singleNote objectForKey:@"note title"];
NSString *notesummary = [singleNote objectForKey:@"note summary"];
NSString *noteid = [singleNote objectForKey:@"note id"];
NSString *notecontent = [singleNote objectForKey:@"note content"];
NSLog(@"Note Title: %@",notetitle);
NSLog(@"Note Summary: %@",notesummary);
NSLog(@"Note ID: %@",noteid);
NSLog(@"Note Content: %@",notecontent);
newNote = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:appDelegate.managedObjectContext];
[newNote setValue:notecontent forKey:@"content"];
[newNote setValue:notesummary forKey:@"summary"];
[newNote setValue:notetitle forKey:@"title"];
[newNote setValue:noteid forKey:@"ID"];
// NSDate *createdDate =
// NSDate *updatedDate =
NSError *error = nil;
if (![appDelegate.managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
[noteFetch release];
app.networkActivityIndicatorVisible = NO;
}
}
if (response.status == 404) {
NSLog(@"FAIL\n%@", [response asString]);
app.networkActivityIndicatorVisible = NO;
}
}];
}
It seems that, however, I'm getting an error when it comes to calling the appDelegate.managedObjectContext
and it just errors out saying the following:
2011-03-03 12:11:01.616 Notacious[182:307] -[NSManagedObjectContext performFetch:]: unrecognized selector sent to instance 0x1474e0
2011-03-03 12:11:01.781 Notacious[182:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSManagedObjectContext performFetch:]: unrecognized selector sent to instance 0x1474e0'
I have already tried setting it to appDelegate.managedObjectContext_
but to avail, it seems to return an error stating that it isn't found within the appDelegate and that it isn't a getter object. However, it is clearly allocated here: http://cl.ly/4xdX
EDIT
Thought I'd best edit this to add in my current work around and another question underneath the original title. The following code is what I have built and is working perfectly fine (except the Edited string isn't being saved and in turn resulting in the following question of mine here).
-(void)syncNotes {
UIApplication *app = [UIApplication alloc];
app.networkActivityIndicatorVisible = YES;
NSDictionary *params = [NSDictionary dictionaryWithObject:authToken forKey:@"api_key"];
[[LRResty client] get:@"http://notacio.us/api/note" parameters:params withBlock:^(LRRestyResponse *response){
if(response.status == 200) {
// NSLog(@"Successful Connection \n%@", [response asString]);
// Create SBJSON object to parse JSON
SBJSON *parser = [[SBJSON alloc] init];
// parse the JSON string into an object - assuming [response asString] is a NSString of JSON data
NSDictionary *object = [parser objectWithString:[response asString] error:nil];
[parser release];
NSFetchRequest *noteFetch;
NSManagedObject *newNote;
appDelegate =(NotaciousAppDelegate *) [[UIApplication sharedApplication] delegate];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Note" inManagedObjectContext:appDelegate.managedObjectContext];
NSArray *fetchedNotes;
NSArray *notes = [object valueForKey:@"result"];
for (NSDictionary *singleNote in notes){
noteFetch=[[NSFetchRequest alloc] init];
[noteFetch setEntity:entity];
NSPredicate *pred=[NSPredicate predicateWithFormat:@"ID==%@",[singleNote objectForKey:@"note id"]];
[noteFetch setPredicate:pred];
NSError *fetchError=nil;
fetchedNotes=[appDelegate.managedObjectContext executeFetchRequest:noteFetch error:&fetchError];
if (fetchError!=nil) {
NSLog(@"syncNotes fetchError=%@,details=%@",fetchError,fetchError.userInfo);
}
if ([fetchedNotes count]==0) {
NSString *notelocked = [singleNote objectForKey:@"note locked"];
NSString *notecreated = [singleNote objectForKey:@"note created"];
NSString *noteupdated = [singleNote objectForKey:@"note updated"];
NSString *notetitle = [singleNote objectForKey:@"note title"];
NSString *notesummary = [singleNote objectForKey:@"note summary"];
NSString *noteid = [singleNote objectForKey:@"note id"];
NSString *notecontent = [singleNote objectForKey:@"note content"];
NSString *formattedTitle = [NSString decodeShit:notetitle];
NSString *formattedSummary = [NSString decodeShit:notesummary];
NSString *formattedContent = [NSString decodeShit:notecontent];
NSLog(@"Note Title: %@",formattedTitle);
NSLog(@"Note Summary: %@",formattedSummary);
NSLog(@"Note ID: %@",noteid);
NSLog(@"Note Content: %@",formattedContent);
NSLog(@"Note Created: %@",notecreated);
NSLog(@"Note Updated: %@",noteupdated);
NSLog(@"Note Locked: %@",notelocked);
newNote = [NSEntityDescription insertNewObjectForEntityForName:@"Note" inManagedObjectContext:appDelegate.managedObjectContext];
[newNote setValue:formattedContent forKey:@"content"];
[newNote setValue:formattedSummary forKey:@"summary"];
[newNote setValue:formattedTitle forKey:@"title"];
[newNote setValue:noteid forKey:@"ID"];
[newNote setValue:notecreated forKey:@"created"];
[newNote setValue:noteupdated forKey:@"updated"];
[newNote setValue:notelocked forKey:@"locked"];
NSError *error = nil;
if (![appDelegate.managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
[noteFetch release];
}
app.networkActivityIndicatorVisible = NO;
}
if (response.status == 404) {
NSLog(@"FAIL\n%@", [response asString]);
app.networkActivityIndicatorVisible = NO;
}
}];
}
Now, sure this works, but when the content string is different, I want to update the correct note. Is there anyone on here that is willing to detail how to do this?
I know I keep asking questions on here, but want to get everything perfect and it seems my knowledge of such simple tasks is somewhat not there. Any input would be greatly appreciated!
EDIT
Ah, another request. If there is no noteID for a currently stored note, then remove that from the Core Data? Is that even possible?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
错误的直接根源是您将
save:error:
消息发送到不存在的托管对象上下文。反过来,托管对象上下文也不存在,因为您从未在上下文中创建或插入托管对象newNote
。我的印象是,您还没有完全理解 Core Data 是围绕对象而不是 SQL 表、列、行等构建的。Core Data 中的每一条数据都存储在一个或多个对象或它们之间的关系中。所有这些对象和关系都会创建对象图,而核心数据真正管理的是该图。
在您的例子中,每条 JSON 消息都会分解为许多字典,每个字典都包含一个注释的数据。您需要一个配置有
Event
实体的托管对象来存储每个注释。如果您从使用 Xcode 中的模板的核心数据之一开始,您将看到您获得了托管对象上下文、托管对象模型、持久性存储协调器和持久性存储,所有这些设置都已为您设置并分配给应用程序委托的属性。在下面的代码中,我将使用模板中的属性和名称。
你需要这样的东西(我没有编译这个,所以要注意拼写错误):
要点:
更新:
要检查预先存在的注释,您需要尝试获取与新数据匹配的现有注释。这是简单的实现(未编译):
您可以使用
IN
测试形成一个谓词,该谓词将针对所有新的“noteID 值”的数组进行测试,并且仅执行一次获取,但这有点复杂。除非您一次处理数百个笔记,否则从用户的角度来看,这种技术看起来同样快。The immediate source of your error is that you are sending the
save:error:
message to a non-existant managed object context. In turn, the managed object context doesn't exist because you never created or inserted the managed objectnewNote
into a context to begin with.I get the impression that you haven't quite grasp that Core Data is built around objects instead of SQL tables, columns, rows etc. Every piece of data in Core Data is stored in one or more objects or the relationships between. All those objects and relationships create and object graph and it is that graph that Core Data really manages.
In your case, every JSON message decomposes into to numerous dictionaries, each one containing the data for one note. You need one managed object configured with the
Event
entity, to store each note.If you start with one of the Core Data using templates in Xcode, you will see that you get the managed object context, managed object model, persistent store coordinator and persistent stores all setup for you and assigned to attributes of the app delegate. In the following code I will use the attributes and names from the template.
You need something like this (I didn't compile this so watch for typos):
Key points:
Update:
To check for a pre-existing note, you need to attempt to fetch existing notes matching the new data. Here's simple implementation (uncompiled):
You can form a predicate using the
IN
test that would test against an array of all the new ``noteID values and do just one fetch but that is a little more complex. Unless you are processing hundreds of notes at a time, this technique will look just as fast from the user's perspective.您只需调用 insertNewObjectForEntityForName ,它总是创建一个新对象。使用唯一值作为键,为该键创建一个获取请求,如果它没有返回任何内容,则创建一个新对象。
You're just calling insertNewObjectForEntityForName which always creates a new object. Use a unique value as the key, create a fetch request for that key, and if it returns nothing, then you create a new object.
您的头文件 ( http://cl.ly/4rz2 ) 有一个名为 newNote 的 Event 对象的引用。但您永远不会创建一个对象来存储在该引用中。我会删除头文件中的引用,并将其保留在 JSON 解析方法中。为 json 中遇到的每个 singleNote 创建一个事件:
不相关
[UIApplication alloc]
不是您通常想要做的事情。您可能想要使用类似以下内容的内容:[UIApplication sharedApplication].n networkActivityIndicatorVisible = YES;
Your header file ( http://cl.ly/4rz2 ) has a reference for an Event object, called newNote. But you never create an object to store in that reference. I would remove the reference in your header file, and keep it local in your JSON parsing method. Create one event for each singleNote you encounter in the json:
Unrelated
[UIApplication alloc]
is not something you normally want to do. You probably want to use something like:[UIApplication sharedApplication].n networkActivityIndicatorVisible = YES;