Добавление объектов из массива в базовые данные - PullRequest
2 голосов
/ 11 февраля 2011

Итак, в течение последних двух дней я боролся с чем-то, что, честно говоря, должно быть простой задачей. Вот небольшое введение в то, чего я пытаюсь достичь.

Я использую собственный веб-сервис, отправляю запрос и обрабатываю возвращенный JSON с помощью SBJSON. Я знаю, чего хочу добиться с помощью этого проанализированного 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", "title note": "Car", "summary note": "", "note note": "", "note note": "1297130179", "note_updated ":" 1297233954" }, {"идентификатор заметки": "252", "заголовок заметки": "Премиум пользователи", "сводка заметок": "", "содержимое заметки": "", "заметка создана": "1296046367", "note_updated": " 1296699888" }, {"note id": "253", "заголовок заметки": "Welcome!", "сводка заметок": "", "содержимое заметки": "", "примечание создано": "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!"
).'

Любые идеи или примеры кода помогут. Мне действительно нужно исправить это, все зависит от того, как это хранится.

EDIT

Вот как мы строим запрос и анализируем возвращаемую строку.

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

EDIT Просто подумал, что дам людям знать, что в настоящее время я использую платформу Resty RESTful, чтобы звонить в свой собственный API. Я подумал, что это лучшая альтернатива и самый простой способ для меня создать упаковку для него. Вот полный запрос. Остальная документация.

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

    }];

 }

EDIT

Итак, теперь, когда я исправил проблему JSON и собираю отдельные строки и тому подобное из каждого массива, у меня возникают проблемы с сохранением проанализированных строк в Базовых данных.

Я покажу вам, что у меня есть.

[newNote] - это имя, данное сущности Базовых данных в заголовочном файле следующего:

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

Любая помощь была бы великолепна, я хотел бы услышать, что другие думают, что проблема. Я не получаю никаких ошибок с приведенным выше кодом, просто ничего не вставляется в базовые данные и, в свою очередь, не отображается в моем UITableView в RootViewController ...

Ответы [ 2 ]

2 голосов
/ 11 февраля 2011

Первое, что я хотел бы сделать, это записать, что возвращает эта строка:

[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
}
0 голосов
/ 25 февраля 2011

Это связано с тем, что [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"];

}

опять же, это просто грязный пример того, что вы могли бы сделать, чтобы решить эту проблему.

...