将数组中的对象添加到核心数据中

时间:2011-02-11 00:17:19

标签: cocoa-touch core-data nsarray nsmanagedobject

所以,在过去两天左右的时间里,我一直在努力做一些诚实应该是一项简单任务的事情。这里有一些关于我想要实现的内容的介绍。

我正在做的是利用我自己的Web服务,发送请求并使用SBJSON解析返回的JSON。我知道用这个解析过的JSON想要完成的是将它插入到Core Data中。

我已经构建了一个对象模型,如下所示:

#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

这些都是针对正在解析的内容构建的,我想我可能不得不在以后将NSDate更改为NSStrings,但现在它们是NSDates。

所以,现在向您展示正在解析的内容。 JSON返回以下内容。

[{“note id”:“525”,“note title”:“Car”,“note summary”:“”,“note content”:“”,“note created”:“1297130179”,“note_updated “:” 1297233954" }, {“note id”:“252”,“note title”:“Premium Users”,“note summary”:“”,“note content”:“”,“note created”:“1296046367”,“note_updated”:“ 1296699888" }, {“note id”:“253”,“note title”:“Welcome!”,“note summary”:“”,“note content”:“”,“note created”:“1296046367”,“note_updated”:“ 1296561871" }]

我想要做的是创建一个实体“Event”,每个实体都存储该事件的相应值。容易,对吗?显然不适合我。

我尝试过的......

 NotaciousAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

            NSManagedObjectContext *context = [appDelegate      managedObjectContext];

            NSManagedObject *newNote;

            newNote = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:context];

            [newNote setValue:[object valueForKey:@"note title"] forKey:@"title"];
            [newNote setValue:[object valueForKey:@"note summary"] forKey:@"summary"];
            [newNote setValue:[object valueForKey:@"note updated"] forKey:@"updated"];

            NSError *error;
            [context save:&error];

但这会返回错误。

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for attribute: property = "title"; desired type = NSString; given type = __NSArrayI; value = (
Car,
"Premium Users",
"Welcome!"
).'

任何想法或代码示例都会有所帮助。我真的需要修复它,所有这些都取决于它的存储方式。

修改

以下是我们如何构建请求并解析返回的字符串。

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];

修改 我想我会让人们知道我目前正在使用Resty RESTful框架来调用我自己的API。我认为这是我自己为它构建包装器的最佳选择和最简单的方法。这是完整的请求。 Resty documentation.

 -(void)pullNotes {

    NSDictionary *params = [NSDictionary dictionaryWithObject:api_key forKey:@"api_key"];   

    [[LRResty client] get:url 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];



            NotaciousAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
            NSManagedObjectContext *context = [appDelegate managedObjectContext];
            NSManagedObject *newNote;

            newNote = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:context];

            [newNote setValue:[object valueForKey:@"note title"] forKey:@"title"];
            [newNote setValue:[object valueForKey:@"note summary"] forKey:@"summary"];
            [newNote setValue:[object valueForKey:@"note updated"] forKey:@"updated"];

            NSError *error;
            [context save:&error];

        }
        if (response.status == 404) {
            NSLog(@"FAIL\n%@", [response asString]);
        }

    }];

 }

修改

所以,既然我已经修复了JSON问题并从每个数组中抓取了各个字符串,那么我就会将解析后的字符串存储到Core Data中。

我会告诉你我现在拥有的东西。

[newNote]是以下头文件中为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"];

                // NSDate *createdDate = 
                // NSDate *updatedDate =

                // If appropriate, configure the new managed object.
                [newNote setValue:notetitle forKey:@"title"];
                [newNote setValue:notesummary forKey:@"summary"];
                [newNote setValue:noteid forKey:@"ID"];
                [newNote setValue:notecontent forKey:@"content"];


                NSLog(@"value is %@", notetitle);

                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();
                }


                [tableView reloadData];

                app.networkActivityIndicatorVisible = NO;

            }


        }
        if (response.status == 404) {
            NSLog(@"FAIL\n%@", [response asString]);
            app.networkActivityIndicatorVisible = NO;
        }

    }];

}

@end

但是,运行此代码实际上并不将字符串存储到Core Data实体中。正如你所看到的那样,它没有最终确定,很多注释代码,但基础是存在的。无论如何,我很好奇是否实际上是从RootViewController中提取笔记本身实现这一点......

在viewDidLoad()中,我正在调用以下内容......

 ntIndex = [IndexNotes alloc];
ntIndex.api_key = api_key;
ntIndex.tableView = self.tableView;
[ntIndex pullNotes];
[ntIndex release];
[self.tableView reloadData];
}

任何帮助都会很棒,我很想听听其他人的想法。我没有上面的代码有任何错误,只是没有任何内容插入到Core Data中,反过来也没有显示在RootViewController的UITableView中......

2 个答案:

答案 0 :(得分:2)

我要做的第一件事就是记录这一行返回的内容:

[object valueForKey:@"note title"]

你会发现它不是你期望的字符串,而是一系列音符标题。

例如:

NSLog(@"value is %@", [object valueForKey:@"note title"]);

然后你需要修复你的JSON或改变你解析它的方式。

编辑: 所以当我说修复你的JSON时,我不是专家,但我认为它应该是这样的:

{"result":[{"note id":"525","note title":"Car","note summary":"","note content":"","note created":"1297130179","note_updated":"1297233954"}, {"note id":"252","note title":"Premium Users","note summary":"","note content":"","note created":"1296046367","note_updated":"1296699888"}, {"note id":"253","note title":"Welcome!","note summary":"","note content":"","note created":"1296046367","note_updated":"1296561871"}]}

然后:

NSDictionary *object = [parser objectWithString:[response asString] error:nil];
NSArray notes = [object valueForKey:@"result"];
for (NSDictionary *singleNote in notes){
    [singleNote objectForKey:"note title"] //this gives you the title of the current note your on
}

答案 1 :(得分:0)

这与[object valueForKey:@"note title"]返回数组的事实有关。

你想要插入更像[[object valueForKey:@"note title"] objectAtIndex:1]的东西来从数组中取出一个对象。但是,确定要从标题数组插入的索引是最难的部分。

修改 在查看了其他一些回复后,它显然将所有标题都归还给一个对象。你的JSON还有一些令人难以置信的时髦。解决这个问题的方法是可能循环来自JSON请求的结果集,并使用此循环中的索引插入正确的标题。

例如:

int count;
for (count = 0; count < [[object valueForKey:@"note title"] count]; count++)
{
   // Do your other insert stuff here
   [newNote setValue:[[object valueForKey:@"note title"] objectAtIndex:count] forKey:@"title"];

}

这再一次只是你可能做的一个肮脏的例子,所以解决了这个问题。