Làm cách nào để phân tích cú pháp JSON với Objective-C?


114

Tôi mới sử dụng iPhone. Có ai có thể cho tôi biết các bước cần làm theo để phân tích cú pháp dữ liệu này và lấy chi tiết hoạt động, tên và họ không?

{
    "#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
Đảm bảo rằng bạn đánh dấu một câu trả lời là được chấp nhận nếu nó giúp ích cho mục đích của bạn.
radu florescu

Câu trả lời:


174

Với viễn cảnh ra mắt OS X v10.7 và iOS 5, có lẽ điều đầu tiên bạn nên làm là NSJSONSerializationtrình phân tích cú pháp JSON do Apple cung cấp. Chỉ sử dụng các tùy chọn của bên thứ ba làm phương án dự phòng nếu bạn thấy rằng lớp đó không khả dụng trong thời gian chạy.

Ví dụ:

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
Bạn có thể đăng bất kỳ ví dụ nào về cách hoạt động của nó? Tôi thấy thiếu tài liệu của Apple.
Robert Karl

@RobertKarl Tôi đã cập nhật câu trả lời của mình; hy vọng rằng làm rõ mọi thứ?
Tommy

Đúng! Cảm ơn bạn, nó hữu ích. Đặc biệt, những gì cần chuyển cho các tùy chọn và tham số lỗi hơi khó hiểu mà không có ví dụ làm việc (tôi không tìm thấy trong tài liệu của họ). Tại sao nhà phát triển chuyển một tham chiếu đến con trỏ lỗi vẫn là một bí ẩn đối với tôi.
Robert Karl

1
@RobertKarl chỉ là một cách dễ dàng để có một phương thức trả về hai thứ thay vì một; nó cũng thường có nghĩa là cái thứ hai là tùy chọn - đối với hầu hết các phương pháp với mẫu đó, việc cung cấp nil là hợp lệ và chỉ dẫn đến việc bạn không nhận được thông tin đó.
Tommy

Vâng, tôi rất vui vì Apple cuối cùng đã thêm vào NSJSONSerialization. Tôi sử dụng điều này ngay bây giờ thay vì json-framework.
Alex

23

Đừng phát minh lại bánh xe. Sử dụng json-framework hoặc thứ gì đó tương tự.

Nếu bạn quyết định sử dụng json-framework, đây là cách bạn sẽ phân tích cú pháp chuỗi JSON thành một 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
Đối với 'một cái gì đó tương tự', json.org liệt kê năm trình phân tích cú pháp JSON cho Objective-C.

4
Lưu ý rằng giấy phép 'của nó không phải là giấy phép Mã nguồn mở tiêu chuẩn. Bạn có thể phải xem lại nó trước khi sử dụng thư viện.
Ravindranath Akila

2
Việc sử dụng này có thực sự mang lại bất kỳ lợi thế NSJSONSerializationnào không?
Kiran

Tại sao lỗi xây dựng: Không có @interface hiển thị cho 'SBJson4Parser' khai báo bộ chọn 'objectWithString:'
Gank

7
Đây thực sự là một trong những lời khuyên tồi tệ nhất để đưa ra. Điều quan trọng là phải học và hiểu về cách mọi thứ hoạt động hơn là chỉ sử dụng một khuôn khổ mỗi khi bạn gặp một cái gì đó phức tạp, bởi vì điều đó không dạy. Các khung công tác của bên thứ 3 cũng không phải là những viên đạn bạc và có thể có nhiều lỗi, không hiệu quả hoặc chỉ là tệ hại. Nói rằng bạn nên sử dụng một khuôn khổ và đừng lo lắng về nó là lời khuyên tồi tệ nhất để đưa ra vì những gì bạn thực sự đang nói là "Đừng học, chỉ sử dụng một khuôn khổ và tiết kiệm thời gian".
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"]);

}

tập tin:

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

Phân tích cú pháp JSON bằng 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"]]);
            }
            
          }

     }

Bạn có thể thấy đầu ra của Bảng điều khiển như dưới đây:

Họ - Tên: Chandra Bhusan - Pandey

Họ - Tên: Kalaiyarasan - Balu

Firstname - Lastname: (null) - (null)

Firstname - Họ: Girija - S

Firstname - Họ: Girija - S

Firstname - Lastname: (null) - (null)


6
  1. Tôi đề xuất và sử dụng TouchJSON để phân tích cú pháp JSON.
  2. Để trả lời bình luận của bạn cho Alex. Đây là mã nhanh sẽ cho phép bạn lấy các trường như activity_details, last_name, v.v. từ từ điển json được trả về:

    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"]);
        }
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.