ฉันจะแยกวิเคราะห์ JSON ด้วย Objective-C ได้อย่างไร


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ตัวแยกวิเคราะห์ JSON ที่ Apple ให้มา ใช้อ็อพชันของ บริษัท อื่นเป็นทางเลือกเท่านั้นหากคุณพบว่าคลาสนั้นไม่พร้อมใช้งานในรันไทม์

ตัวอย่างเช่น:

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ผมใช้ตอนนี้แทน
Alex

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จะแสดงตัวแยกวิเคราะห์ JSON ห้าตัวสำหรับ Objective-C

4
โปรดทราบว่า 'ใบอนุญาตไม่ใช่ใบอนุญาตโอเพนซอร์สมาตรฐาน คุณอาจต้องตรวจสอบก่อนใช้ห้องสมุด
Ravindranath Akila

2
การใช้สิ่งนี้ให้ประโยชน์มากกว่าจริงNSJSONSerializationหรือไม่?
Kiran

เหตุใดจึงสร้างข้อผิดพลาด: ไม่ปรากฏ @ อินเทอร์เฟซสำหรับ 'SBJson4Parser' ประกาศตัวเลือก 'objectWithString:'
Gank

7
นี่เป็นคำแนะนำที่แย่ที่สุดที่จะให้ สิ่งสำคัญคือต้องเรียนรู้และทำความเข้าใจเกี่ยวกับวิธีการทำงานของสิ่งต่างๆแทนที่จะใช้กรอบทุกครั้งที่คุณทำอะไรที่ซับซ้อนเพราะนั่นไม่ได้สอน เฟรมเวิร์กของบุคคลที่สามไม่ใช่กระสุนเงินและอาจเต็มไปด้วยข้อบกพร่องความไร้ประสิทธิภาพหรือเพียงแค่ดูด การบอกว่าคุณควรใช้กรอบและไม่ต้องกังวลว่านี่เป็นคำแนะนำที่แย่ที่สุดที่ควรให้เนื่องจากสิ่งที่คุณพูดจริงๆคือ "อย่าเรียนรู้เพียงแค่ใช้กรอบและประหยัดเวลา"
TheM00s3

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

การแยกวิเคราะห์ JSON โดยใช้ NSJSONSerialization

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

     }

คุณสามารถดูผลลัพธ์ของคอนโซลได้ดังต่อไปนี้:

ชื่อ - นามสกุล: จันทราภู่เสน - ใบเตย

ชื่อ - นามสกุล: กลัยยาราสาน - บาลู

ชื่อ - นามสกุล: (null) - (null)

ชื่อ - นามสกุล: Girija - S

ชื่อ - นามสกุล: Girija - S

ชื่อ - นามสกุล: (null) - (null)


6
  1. ฉันแนะนำและใช้TouchJSONสำหรับการแยกวิเคราะห์ JSON
  2. เพื่อตอบความคิดเห็นของคุณอเล็กซ์ นี่คือรหัสด่วนที่จะช่วยให้คุณได้รับฟิลด์เช่น activity_details, last_name และอื่น ๆ จากพจนานุกรม json ที่ส่งคืน:

    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.