Objective-C로 JSON을 어떻게 구문 분석합니까?


114

저는 iPhone을 처음 사용합니다. 누구든지이 데이터를 구문 분석하고 활동 세부 정보, 이름 및 성을 얻기 위해 따라야 할 단계를 알려줄 수 있습니까?

{
    "#error": false, 
    "#data": {
        "": {
            "activity_id": "35336", 
            "user_id": "1", 
            "user_first_name": "Chandra Bhusan", 
            "user_last_name": "Pandey", 
            "time": "1300870420", 
            "activity_details": "Good\n", 
            "activity_type": "status_update", 
            "photo_url": "http://184.73.155.44/hcl-meme/QA_TEST/sites/default/files/pictures/picture-1627435117.jpg"
        }, 
        "boolean": "1", 
        "1": {
            "1": {
                "photo_1_id": "9755"
            }, 
            "activity_id": "35294", 
            "album_name": "Kalai_new_Gallery", 
            "user_id": "31", 
            "album_id": "9754", 
            "user_first_name": "Kalaiyarasan", 
            "user_last_name": "Balu", 
            "0": {
                "photo_0_id": "9756"
            }, 
            "time": "1300365758", 
            "activity_type": "photo_upload", 
            "photo_url": "http://184.73.155.44/hcl-meme/QA_TEST/"
        }, 
        "3": {
            "activity_id": "35289", 
            "user_id": "33", 
            "user_first_name": "Girija", 
            "user_last_name": "S", 
            "time": "1300279636", 
            "activity_details": "girija Again\n", 
            "activity_type": "status_update", 
            "photo_url": "http://184.73.155.44/hcl-meme/QA_TEST/sites/default/files/pictures/picture-33-6361851323080768.jpg"
        }, 
        "2": {
            "owner_first_name": "Girija", 
            "activity_id": "35290", 
            "activity_details": "a:2:{s:4:\"html\";s:51:\"!user_fullname and !friend_fullname are now friends\";s:4:\"type\";s:10:\"friend_add\";}", 
            "activity_type": "friend accept", 
            "owner_last_name": "S", 
            "time": "1300280400", 
            "photo_url": "http://184.73.155.44/hcl-meme/QA_TEST/sites/default/files/pictures/picture-33-6361851323080768.jpg", 
            "owner_id": "33"
        }, 
        "4": {
            "activity_id": "35288", 
            "user_id": "33", 
            "user_first_name": "Girija", 
            "user_last_name": "S", 
            "time": "1300279530", 
            "activity_details": "girija from mobile\n", 
            "activity_type": "status_update", 
            "photo_url": "http://184.73.155.44/hcl-meme/QA_TEST/sites/default/files/pictures/picture-33-6361851323080768.jpg"
        }
    }
}

1
귀하의 원인에 도움이 되었다면 답변을 수락 됨으로 표시하십시오.
radu florescu

답변:


174

OS X v10.7 및 iOS 5 출시의 관점에서 볼 때 지금 가장 먼저 권장 할 것은 NSJSONSerialization Apple에서 제공 한 JSON 파서 일 것입니다. 런타임에 해당 클래스를 사용할 수없는 경우에만 타사 옵션을 대체 옵션으로 사용하십시오.

예를 들면 다음과 같습니다.

NSData *returnedData = ...JSON data, probably from a web request...

// probably check here that returnedData isn't nil; attempting
// NSJSONSerialization with nil data raises an exception, and who
// knows how your third-party library intends to react?

if(NSClassFromString(@"NSJSONSerialization"))
{
    NSError *error = nil;
    id object = [NSJSONSerialization
                      JSONObjectWithData:returnedData
                      options:0
                      error:&error];

    if(error) { /* JSON was malformed, act appropriately here */ }

    // the originating poster wants to deal with dictionaries;
    // assuming you do too then something like this is the first
    // validation step:
    if([object isKindOfClass:[NSDictionary class]])
    {
        NSDictionary *results = object;
        /* proceed with results as you like; the assignment to
        an explicit NSDictionary * is artificial step to get 
        compile-time checking from here on down (and better autocompletion
        when editing). You could have just made object an NSDictionary *
        in the first place but stylistically you might prefer to keep
        the question of type open until it's confirmed */
    }
    else
    {
        /* there's no guarantee that the outermost object in a JSON
        packet will be a dictionary; if we get here then it wasn't,
        so 'object' shouldn't be treated as an NSDictionary; probably
        you need to report a suitable error condition */
    }
}
else
{
    // the user is using iOS 4; we'll need to use a third-party solution.
    // If you don't intend to support iOS 4 then get rid of this entire
    // conditional and just jump straight to
    // NSError *error = nil;
    // [NSJSONSerialization JSONObjectWithData:...
}

1
이것이 어떻게 작동하는지에 대한 예를 게시 할 수 있습니까? Apple 문서가 부족하다는 것을 알고 있습니다.
Robert Karl

@RobertKarl 내 답변을 업데이트했습니다. 바라건대 그게 명확 해 졌나요?
Tommy

예! 감사합니다. 도움이됩니다. 특히 옵션 및 오류 매개 변수에 대해 전달할 내용은 작업 예제가 없으면 다소 신비 스럽습니다 (문서에서 찾을 수 없음). 개발자가 오류 포인터에 대한 참조를 전달하는 이유는 여전히 수수께끼입니다.
Robert Karl

1
@RobertKarl은 하나가 아닌 두 가지를 반환하는 메서드를 갖는 쉬운 방법입니다. 또한 일반적으로 두 번째 것은 선택 사항이라는 것을 의미합니다. 해당 패턴을 사용하는 대부분의 메소드에서 nil을 제공하는 것은 유효하며 단순히 해당 정보를 얻지 못하게됩니다.
Tommy

그래, 나는 애플이 드디어 추가해서 너무 기쁘다 NSJSONSerialization. 나는 대신 이것을 사용합니다 json-framework.
알렉스

23

바퀴를 재발 명하지 마십시오. json-framework 또는 유사한 것을 사용하십시오 .

json-framework를 사용하기로 결정한 경우 JSON 문자열을 다음과 같이 구문 분석하는 방법은 NSDictionary다음과 같습니다.

SBJsonParser* parser = [[[SBJsonParser alloc] init] autorelease];
// assuming jsonString is your JSON string...
NSDictionary* myDict = [parser objectWithString:jsonString];

// now you can grab data out of the dictionary using objectForKey or another dictionary method

3
'유사한 것'에 대해 json.org 는 Objective-C에 대한 5 개의 JSON 파서를 나열합니다.

4
해당 라이선스는 표준 오픈 소스 라이선스가 아닙니다. 라이브러리를 사용하기 전에 검토해야 할 수도 있습니다.
Ravindranath Akila

2
이것을 사용하면 실제로 이점이 NSJSONSerialization있습니까?
Kiran

빌드 오류 이유 : 'SBJson4Parser'에 대한 @interface가 보이지 않는 이유는 'objectWithString :'선택자를 선언합니다.
Gank

7
이것은 정말 최악의 조언 중 하나입니다. 복잡한 일을 할 때마다 프레임 워크를 사용하는 것보다 일이 어떻게 작동하는지 배우고 이해하는 것이 중요합니다. 써드 파티 프레임 워크도 은탄이 아니며 버그, 비 효율성으로 가득 차거나 그냥 짜증나게 할 수 있습니다. 프레임 워크를 사용해야하고 그것에 대해 걱정하지 않는다고 말하는 것은 당신이 정말로 말하는 것이 "배우지 말고 프레임 워크를 사용하고 시간을 절약하라"이기 때문에 가장 나쁜 조언입니다.
TheM00s3 2015

21
NSString* path  = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"json"];

//将文件内容读取到字符串中,注意编码NSUTF8StringEncoding 防止乱码,
NSString* jsonString = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];

//将字符串写到缓冲区。
NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];

NSError *jsonError;
id allKeys = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONWritingPrettyPrinted error:&jsonError];


for (int i=0; i<[allKeys count]; i++) {
    NSDictionary *arrayResult = [allKeys objectAtIndex:i];
    NSLog(@"name=%@",[arrayResult objectForKey:@"storyboardName"]);

}

파일:

 [
  {
  "ID":1,
  "idSort" : 0,
  "deleted":0,
  "storyboardName" : "MLMember",
  "dispalyTitle" : "76.360779",
  "rightLevel" : "10.010490",
  "showTabBar" : 1,
  "openWeb" : 0,
  "webUrl":""
  },
  {
  "ID":1,
  "idSort" : 0,
  "deleted":0,
  "storyboardName" : "0.00",
  "dispalyTitle" : "76.360779",
  "rightLevel" : "10.010490",
  "showTabBar" : 1,
  "openWeb" : 0,
  "webUrl":""
  }
  ]

12

NSJSONSerialization을 사용한 JSON 구문 분석

   NSString* path  = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"json"];
   
    //Here you can take JSON string from your URL ,I am using json file
    NSString* jsonString = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    NSError *jsonError;
    NSArray *jsonDataArray = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:&jsonError];
  
    NSLog(@"jsonDataArray: %@",jsonDataArray);

    NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&jsonError];
if(jsonObject !=nil){
   // NSString *errorCode=[NSMutableString stringWithFormat:@"%@",[jsonObject objectForKey:@"response"]];
   
        
        if(![[jsonObject objectForKey:@"#data"] isEqual:@""]){
            
            NSMutableArray *array=[jsonObject objectForKey:@"#data"];
             // NSLog(@"array: %@",array);
            NSLog(@"array: %d",array.count);  
            
            int k = 0;
            for(int z = 0; z<array.count;z++){
                
                NSString *strfd = [NSString stringWithFormat:@"%d",k];
                NSDictionary *dicr = jsonObject[@"#data"][strfd];
                k=k+1;
                // NSLog(@"dicr: %@",dicr);
                 NSLog(@"Firstname - Lastname   : %@ - %@",
                     [NSMutableString stringWithFormat:@"%@",[dicr objectForKey:@"user_first_name"]],
                     [NSMutableString stringWithFormat:@"%@",[dicr objectForKey:@"user_last_name"]]);
            }
            
          }

     }

다음과 같이 콘솔 출력을 볼 수 있습니다.

이름-성 : Chandra Bhusan-Pandey

이름-성 : Kalaiyarasan-Balu

이름-성 : (null)-(null)

이름-성 : Girija-S

이름-성 : Girija-S

이름-성 : (null)-(null)


6
  1. JSON 구문 분석을 위해 TouchJSON 을 권장하고 사용 합니다.
  2. Alex에게 귀하의 의견에 답하기 위해. 반환 된 json 사전에서 activity_details, last_name 등과 같은 필드를 가져올 수있는 빠른 코드는 다음과 같습니다.

    NSDictionary *userinfo=[jsondic valueforKey:@"#data"];
    NSDictionary *user;
    NSInteger i = 0;
    NSString *skey;
    if(userinfo != nil){
        for( i = 0; i < [userinfo count]; i++ ) {
            if(i)
                skey = [NSString stringWithFormat:@"%d",i];
            else
                skey = @"";
    
            user = [userinfo objectForKey:skey];
            NSLog(@"activity_details:%@",[user objectForKey:@"activity_details"]);
            NSLog(@"last_name:%@",[user objectForKey:@"last_name"]);
            NSLog(@"first_name:%@",[user objectForKey:@"first_name"]);
            NSLog(@"photo_url:%@",[user objectForKey:@"photo_url"]);
        }
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.