2011-02-11 3 views
2

그래서 지난 2 일 동안 나는 솔직히 간단한 작업이어야하는 무언가로 고생했습니다. 여기 내가 달성하려고하는 것에 대한 약간의 소개가 있습니다.배열에서 코어 데이터로 객체 추가

내가하고있는 일은 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은 다음을 반환합니다.

[{ "메모 ID :"525 ","메모 제목 ":"메모 요약 ":" ","메모 내용 ":" "메모 작성": "1297130179" { "note id": "252", "메모 제목": "프리미엄 사용자", "메모 요약": "", "메모 내용": "", "메모 작성 됨":: "note id": "note title": "Welcome!", "note summary": "", "note content": "", "1296046367", "note_updated": "1296699888"}, { "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]; 

편집 그냥 나는 사람들이 내가 현재 내 자신의 API에 내 전화를 만들기 위해 Resty 편안하고 프레임 워크를 사용하고 있음을 알려 줄 알았는데. 나는 이것이 자신을위한 래퍼를 만드는 가장 좋은 대안이고 가장 쉬운 방법이라고 생각했다. 다음은 전체 요청입니다. 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의 문제를 해결하고 각각의 문자열을 잡아하고 및 각 배열에서, 내가 코어 데이터로 분석 된 문자열을 저장하는 문제가있어 것을 .

나는 현재 가지고있는 것을 보여 드리겠습니다.

[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 

그러나이 코드를 실행해도 실제로 문자열이 핵심 데이터 엔티티에 저장되지는 ​​않습니다. 당신이 볼 수 있듯이, 그것은 주석 처리 된 코드가 많이 있지만, 거기에 기초가 있습니다. 어쨌든, 나는

있는 viewDidLoad에서

이() 나는 다음과 같은 ...

를 호출하고 있습니다 ... 그것이 내가 실제로하여 RootViewController에서 노트 자체가 당겨에서이를 구현하는 방법인지 여부에 대한 궁금 해요
ntIndex = [IndexNotes alloc]; 
ntIndex.api_key = api_key; 
ntIndex.tableView = self.tableView; 
[ntIndex pullNotes]; 
[ntIndex release]; 
[self.tableView reloadData]; 
} 

도움이 될 것입니다. 다른 사람들이 그 문제에 대해 어떻게 생각하는지 듣고 싶습니다. 위의 코드에서 오류가 발생하지 않습니다. 핵심 데이터에 아무 것도 삽입되지 않고 차례로 RootViewController의 UITableView에 표시되지 않습니다.

+0

NSString * string = [NSString stringWithFormat : @ "% @", [object valueForKey : @ "note title"]]; 해본 적이 있습니까? 코드에 따라 다음과 같이 시도하십시오. NSString으로 이동하여 CoreData에 저장하십시오. – Frankrockz

+0

newNote.title = [object valueForKey : @ "note title"]; – Frankrockz

답변

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 
} 
+0

위의 NSLogging 후 메모 제목 배열을 반환합니다. 이 문제를 해결하려면 어떻게해야합니까? –

+0

지금 해보기, Russel! –

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

} 

은 다시는 당신이 가능하므로이 문제를 해결 할 수있는 것을 단지 더러운 예입니다.

관련 문제