Come posso analizzare JSON con Objective-C?


114

Sono nuovo su iPhone. Qualcuno può dirmi i passaggi da seguire per analizzare questi dati e ottenere i dettagli dell'attività, il nome e il cognome?

{
    "#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
Assicurati di contrassegnare una risposta come accettata se ha aiutato la tua causa.
radu florescu

Risposte:


174

Con la prospettiva del lancio di OS X v10.7 e iOS 5, probabilmente la prima cosa da consigliare ora è NSJSONSerializationil parser JSON fornito da Apple. Usa le opzioni di terze parti solo come fallback se trovi quella classe non disponibile in fase di esecuzione.

Quindi, ad esempio:

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
Qualche esempio di come funziona che puoi pubblicare? Trovo carente la documentazione Apple.
Robert Karl

@RobertKarl ho aggiornato la mia risposta; speriamo che chiarisca le cose?
Tommy

Sì! Grazie, è utile. In particolare, cosa passare per le opzioni e il parametro di errore sono alquanto mistici senza un esempio funzionante (non ne ho trovato uno nella loro documentazione). Il motivo per cui lo sviluppatore passa un riferimento al puntatore di errore rimane enigmatico per me.
Robert Karl

1
@RobertKarl è solo un modo semplice per avere un metodo che restituisce due cose invece di una; di solito significa anche che il secondo è facoltativo - per la maggior parte dei metodi con quel modello, fornire zero è valido e si traduce semplicemente nel non ottenere quell'informazione.
Tommy

Sì, sono così felice che Apple abbia finalmente aggiunto NSJSONSerialization. Lo uso adesso invece di json-framework.
Alex

23

Non reinventare la ruota. Usa json-framework o qualcosa di simile.

Se decidi di utilizzare json-framework, ecco come analizzare una stringa JSON in un 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
Per quanto riguarda "qualcosa di simile", json.org elenca cinque parser JSON per Objective-C.

4
Si noti che la sua licenza non è una licenza Open Source standard. Potrebbe essere necessario esaminarlo prima di utilizzare la libreria.
Ravindranath Akila

2
L'utilizzo di questo offre davvero qualche vantaggio rispetto a NSJSONSerialization?
Kiran

Perché errore di compilazione: nessuna interfaccia @ visibile per "SBJson4Parser" dichiara il selettore "objectWithString:"
Gank

7
Questo è davvero uno dei peggiori consigli da dare. È importante imparare e capire come funzionano le cose piuttosto che usare semplicemente un framework ogni volta che si colpisce qualcosa di complesso, perché questo non insegna. I framework di terze parti non sono nemmeno proiettili d'argento e possono essere pieni di bug, inefficienze o semplicemente schifo. Dire che dovresti usare un framework e non preoccuparti è il consiglio peggiore da dare poiché quello che stai veramente dicendo è "Non imparare, usa solo un framework e risparmia tempo".
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"]);

}

file:

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

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

     }

Puoi vedere l'output della console come di seguito:

Nome - Cognome: Chandra Bhusan - Pandey

Nome - Cognome: Kalaiyarasan - Balu

Nome - Cognome: (null) - (null)

Nome - Cognome: Girija - S

Nome - Cognome: Girija - S

Nome - Cognome: (null) - (null)


6
  1. Consiglio e utilizzo TouchJSON per l'analisi di JSON.
  2. Per rispondere al tuo commento ad Alex. Ecco un codice rapido che dovrebbe consentirti di ottenere i campi come activity_details, last_name, ecc. Dal dizionario json restituito:

    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"]);
        }
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.