Bagaimana cara mengurai JSON dengan Objective-C?


114

Saya baru mengenal iPhone. Adakah yang bisa memberi tahu saya langkah-langkah yang harus diikuti untuk mengurai data ini dan mendapatkan detail aktivitas, nama depan, dan nama belakang?

{
    "#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
Pastikan Anda menandai jawaban sebagai diterima jika itu membantu tujuan Anda.
radu florescu

Jawaban:


174

Dengan perspektif peluncuran OS X v10.7 dan iOS 5, mungkin hal pertama yang direkomendasikan sekarang adalah NSJSONSerialization, parser JSON yang disediakan Apple. Gunakan opsi pihak ketiga hanya sebagai cadangan jika Anda menemukan kelas tersebut tidak tersedia pada waktu proses.

Jadi, misalnya:

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
Ada contoh cara kerjanya yang dapat Anda posting? Saya menemukan dokumentasi Apple kurang.
Robert Karl

@RobertKarl Saya telah memperbarui jawaban saya; semoga itu menjelaskan sesuatu?
Tommy

Iya! Terima kasih, itu membantu. Secara khusus, apa yang harus dilewatkan untuk opsi dan parameter kesalahan agak mistis tanpa contoh yang berfungsi (saya belum menemukannya di dokumentasi mereka). Mengapa pengembang memberikan referensi ke penunjuk kesalahan tetap membingungkan saya.
Robert Karl

1
@RobertKarl itu hanya cara mudah untuk memiliki metode yang mengembalikan dua hal, bukan satu; itu juga biasanya berarti bahwa yang kedua adalah opsional - untuk sebagian besar metode dengan pola itu, memberikan nil adalah valid dan hanya mengakibatkan Anda tidak mendapatkan informasi itu.
Tommy

Ya saya sangat senang akhirnya Apple menambahkan NSJSONSerialization. Saya menggunakan ini sekarang sebagai ganti json-framework.
Alex

23

Jangan menemukan kembali roda. Gunakan json-framework atau yang serupa.

Jika Anda memutuskan untuk menggunakan json-framework, berikut ini cara Anda mengurai string JSON menjadi 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
Adapun 'sesuatu yang serupa', json.org mendaftar lima parser JSON untuk Objective-C.

4
Perhatikan bahwa 'lisensinya bukan lisensi Sumber Terbuka standar. Anda mungkin harus memeriksanya sebelum menggunakan perpustakaan.
Ravindranath Akila

2
Apakah menggunakan ini benar-benar memberikan keuntungan lebih NSJSONSerialization?
Kiran

Mengapa kesalahan build: @interface tidak terlihat untuk 'SBJson4Parser' mendeklarasikan 'objectWithString' selector: '
Gank

7
Ini benar-benar salah satu nasihat terburuk untuk diberikan. Penting untuk mempelajari dan memahami tentang cara kerja berbagai hal daripada hanya menggunakan kerangka kerja setiap kali Anda menemukan sesuatu yang kompleks, karena itu tidak mengajarkan. Kerangka pihak ketiga juga bukan peluru perak dan dapat penuh dengan bug, inefisiensi, atau hanya payah. Mengatakan bahwa Anda harus menggunakan kerangka kerja dan tidak khawatir tentang itu adalah nasihat terburuk untuk diberikan karena apa yang sebenarnya Anda katakan adalah "Jangan belajar, cukup gunakan kerangka kerja dan hemat waktu".
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"]);

}

mengajukan:

 [
  {
  "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

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

     }

Anda dapat melihat output Konsol seperti di bawah ini:

Nama depan - Nama belakang: Chandra Bhusan - Pandey

Nama depan - Nama belakang: Kalaiyarasan - Balu

Nama depan - Nama belakang: (null) - (null)

Nama depan - Nama belakang: Girija - S

Nama depan - Nama belakang: Girija - S

Nama depan - Nama belakang: (null) - (null)


6
  1. Saya merekomendasikan dan menggunakan TouchJSON untuk mengurai JSON.
  2. Untuk menjawab komentar Anda untuk Alex. Berikut kode cepat yang memungkinkan Anda mendapatkan bidang seperti activity_details, last_name, dll. Dari kamus json yang dikembalikan:

    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"]);
        }
    }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.