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

Posted

技术标签:

【中文标题】将数组中的对象添加到核心数据中【英文标题】:Adding Objects from an Array into Core Data 【发布时间】:2011-02-11 00:17:18 【问题描述】:

所以,在过去两天左右的时间里,我一直在努力解决一些老实说应该是简单的任务。下面是我想要达到的目标的一些介绍。

我正在做的是利用我自己的 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"]

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

我尝试过的...

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

任何帮助都会很棒,我很想听听其他人认为问题所在。上面的代码没有任何错误,只是没有将任何内容插入到核心数据中,而在 RootViewController 中的 UITableView 中也没有显示...

【问题讨论】:

你试过 NSString * string = [NSString stringWithFormat:@"%@", [object valueForKey:@"note title"]];根据您的代码尝试这样的事情。转到 NSString 然后将其保存到 CoreData 你也可以试试 newNote.title = [object valueForKey:@"note title"]; 【参考方案1】:

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

[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

【讨论】:

上面的 NSLogging 之后,它返回一个笔记标题数组。我该如何解决这个问题?【参考方案2】:

这与[object valueForKey:@"note title"] 返回一个数组有关。

您可能想要插入更像[[object valueForKey:@"note title"] objectAtIndex:1] 的内容以从数组中取出一个对象。但是,从标题数组中找出要插入的索引是最困难的部分。

提姆

编辑: 在查看了其他一些响应后,很明显它正在返回一个对象中的所有标题。你的 JSON 有一些非常时髦的东西。解决此问题的一种方法是可能 for 循环您的 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"];


再一次,这只是一个肮脏的例子,说明你可以这样做来解决这个问题。

【讨论】:

以上是关于将数组中的对象添加到核心数据中的主要内容,如果未能解决你的问题,请参考以下文章

将子实体加载到核心数据中的托管对象

将对象添加到具有多对多关系的核心数据中的 NSSet

如何将带有对象的数组中的数据动态添加到嵌套数组中?

将对象添加到java mongodb中的数组

核心数据数组

使用 graphql-compose-mongoose 将对象添加到 mongodb 模型中的对象数组