JSON'u Objective-C ile nasıl ayrıştırırım?


114

İPhone'da yeniyim. Bu verileri ayrıştırmak ve etkinlik ayrıntılarını, adı ve soyadı almak için izlenecek adımları bana herkes söyleyebilir mi?

{
    "#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
Amacınıza yardımcı olduysa bir yanıtı kabul edildi olarak işaretlediğinizden emin olun.
radu florescu

Yanıtlar:


174

OS X v10.7 ve iOS 5 lansmanlarının perspektifiyle, muhtemelen şu anda önerilecek ilk şey NSJSONSerialization, Apple'ın sağladığı JSON ayrıştırıcısıdır. Üçüncü taraf seçeneklerini yalnızca, söz konusu sınıfın çalışma zamanında kullanılamadığını fark ederseniz, yedek olarak kullanın.

Yani mesela:

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
Bunun nasıl çalıştığına dair herhangi bir örnek yayınlayabilirsiniz? Apple belgelerini eksik buluyorum.
Robert Karl

@RobertKarl Cevabımı güncelledim; umarım bu işleri açıklığa kavuşturur?
Tommy

Evet! Teşekkür ederim, bu yardımcı oldu. Özellikle, seçenekler ve hata parametresi için neyin aktarılacağı, çalışan bir örnek olmadan biraz mistiktir (belgelerinde bir tane bulamadım). Geliştiricinin hata işaretçisine neden bir referans ilettiği, benim için gizemli kalıyor.
Robert Karl

1
@RobertKarl, bir yerine iki şeyi döndüren bir yönteme sahip olmanın kolay bir yolu; aynı zamanda genellikle ikincisinin isteğe bağlı olduğu anlamına gelir - bu kalıba sahip çoğu yöntem için, sıfır sağlamak geçerlidir ve basitçe bu bilgiyi alamamanıza neden olur.
Tommy

Evet, Apple'ın sonunda eklediğinden çok mutluyum NSJSONSerialization. Bunu yerine şimdi kullanıyorum json-framework.
Alex

23

Tekerleği yeniden icat etmeyin. Json-framework veya benzeri bir şey kullanın .

Json-framework kullanmaya karar verirseniz, bir JSON dizesini şu şekilde ayrıştırırsınız 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
'Benzer bir şey'e gelince , json.org , Objective-C için beş JSON ayrıştırıcısı listeler.

4
Lisansının standart bir Açık Kaynak lisansı olmadığını unutmayın. Kitaplığı kullanmadan önce gözden geçirmeniz gerekebilir.
Ravindranath Akila

2
Bunu kullanmak gerçekten bir avantaj sağlıyor NSJSONSerializationmu?
Kiran

Neden hata oluştur: 'SBJson4Parser' için görünür bir @ arabirim yok 'objectWithString:' seçicisini bildiriyor
Gank

7
Bu gerçekten verilecek en kötü tavsiyeler arasında. Karmaşık bir şeye her vurduğunuzda bir çerçeve kullanmak yerine, işlerin nasıl yürüdüğünü öğrenmek ve anlamak önemlidir, çünkü bu öğretmez. Üçüncü taraf çerçeveler de sihirli değnek değildir ve böceklerle, verimsizliklerle ya da sadece kötü durumlarla dolu olabilir. Bir çerçeve kullanmanız gerektiğini ve bunun için endişelenmemeniz gerektiğini söylemek, gerçekten söylediğiniz şey "Öğrenmeyin, sadece bir çerçeve kullanın ve zamandan tasarruf edin" olduğundan, verebileceğiniz en kötü tavsiye.
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"]);

}

dosya:

 [
  {
  "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 kullanarak JSON ayrıştırma

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

     }

Konsol çıktısını aşağıdaki gibi görebilirsiniz:

Ad - Soyad: Chandra Bhusan - Pandey

Adı - Soyadı: Kalaiyarasan - Balu

Ad - Soyad: (boş) - (boş)

Ad - Soyad: Girija - S

Ad - Soyad: Girija - S

Ad - Soyad: (boş) - (boş)


6
  1. JSON'u ayrıştırmak için TouchJSON'u öneririm ve kullanırım .
  2. Yorumunuzu Alex'e cevaplamak için. Döndürülen json sözlüğünden activity_details, last_name, vb. Gibi alanları almanıza izin veren hızlı kod:

    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"]);
        }
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.