2009-03-28 59 views
6

Tôi đang viết một ứng dụng gốc của iPhone bằng cách sử dụng khung JSON.Làm thế nào để phân tích cú pháp đối tượng JSON lồng nhau với khuôn khổ JSON và Objective-C/iPhone/Xcode?

Ứng dụng của tôi đang truy cập các dịch vụ web bằng JSON. Các dữ liệu JSON chúng tôi gửi đã lồng các đối tượng, dưới đây là một ví dụ về các dữ liệu phục vụ lên:

{ 
    "model": { 
     "JSONRESPONSE": { 
      "authenticationFlag": true, 
      "sessionId": "3C4AA754D77BFBE33E0D66EBE306B8CA", 
      "statusMessage": "Successful Login.", 
      "locId": 1, 
      "userName": "Joe Schmoe" 
     } 
    } 
} 

Tôi đang gặp vấn đề phân tích bằng cách sử dụng phương pháp objectForKey và valueForKey NSDictionary. Tôi tiếp tục nhận được lỗi runtimeArgumentException thời gian chạy.

Ví dụ: tôi muốn truy vấn dữ liệu phản hồi cho phần tử "authenticationFlag".

Cảm ơn, Mike Seattle

Trả lời

11

Thật khó có thể nói mà không cần một số chi tiết (ví dụ như JSON phân tích mã mà bạn đang sử dụng), nhưng hai điều tấn công tôi càng tốt:

  1. bạn không truy vấn với đường dẫn đầy đủ. Trong trường hợp trên, bạn sẽ cần phải đầu tiên được mô hình kèm theo, phản ứng json, và chỉ sau đó yêu cầu điển phản ứng json cho giá trị authenticationFlag:

    [[[jsonDict objectForKey:@"model"] objectForKey:@"JSONRESPONSE"] objectForKey:@"authenticationFlag"]

  2. có lẽ bạn đang sử dụng c- strings ("") thay vì NSStrings (@"") làm khóa (mặc dù điều này có khả năng sẽ bị lỗi hoặc không biên dịch). Chìa khóa phải là một cái gì đó hơn có thể được đúc thành id.

Trong khi có thể, cả hai có thể là sai, vì vậy vui lòng bao gồm thêm chi tiết.

+0

Giải pháp 1 làm việc. Về cơ bản, tôi cần phải đi qua nút JSONRESPONSE sau đó tôi có thể truy cập phần tử mong muốn. Cảm ơn! – mibrop

1
NSString* aStr; 
    aStr = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; 
    NSDictionary *dictionary = [aStr JSONValue]; 
    NSArray *keys = [dictionary allKeys]; 

    // values in foreach loop 
    for (NSString *key in keys) { 
    NSArray *items = (NSArray *) [dictionary objectForKey:key]; 

     for (id *item in items) { 


      NSString* aStrs= item; 
      NSLog(@" test %@", aStrs); 

      NSDictionary *dict = aStrs; 
      NSArray *k = [dict allKeys]; 

     for (id *it in k) { 
          NSLog(@"the child item: %@", [NSString stringWithFormat:@"Child Item -> %@ value %@", (NSDictionary *) it,[dict objectForKey:it]]);     
         } 
2

Sau đây được lấy trực tiếp từ Hướng dẫn của Dan Grigsby tại - http://mobileorchard.com/tutorial-json-over-http-on-the-iphone/ - Vui lòng quy định, ăn cắp là nghiệp xấu.

Tìm nạp JSON qua HTTP

Chúng tôi sẽ sử dụng yêu cầu HTTP của Cocoa để đưa ra yêu cầu HTTP và truy xuất dữ liệu JSON.

Cocoa cung cấp cả tùy chọn đồng bộ và không đồng bộ để thực hiện yêu cầu HTTP. Các yêu cầu đồng bộ chạy từ runloop chính của ứng dụng khiến ứng dụng tạm dừng trong khi chờ phản hồi. Yêu cầu không đồng bộ sử dụng gọi lại để tránh bị chặn và dễ sử dụng. Chúng tôi sẽ sử dụng các yêu cầu không đồng bộ.

Điều đầu tiên chúng ta cần làm là cập nhật giao diện của bộ điều khiển chế độ xem của chúng tôi để bao gồm NSMutableData để giữ dữ liệu phản hồi. Chúng tôi tuyên bố điều này trong giao diện (và không phải bên trong một phương pháp) bởi vì phản ứng quay trở lại serially trong miếng mà chúng tôi khâu lại với nhau chứ không phải trong một đơn vị hoàn chỉnh.

#import <UIKit/UIKit.h> 

@interface ViewController : UIViewController { 
    IBOutlet UILabel *label; 
    NSMutableData *responseData; 
} 

Để đơn giản, chúng tôi sẽ khởi chạy yêu cầu HTTP từ chế độ xem Tải xuống.

Thay thế nội dung của:

#import "JSON/JSON.h" 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    responseData = [[NSMutableData data] retain]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"XYZ.json"]]; 
    [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    [responseData setLength:0]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    [responseData appendData:data]; 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
    label.text = [NSString stringWithFormat:@"Connection failed: %@", [error description]]; 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    [connection release]; 
} 

- (void)dealloc { 
    [super dealloc]; 
} 

@end 

đang chủ yếu là soạn sẵn này khởi tạo các biến responseData phải sẵn sàng để giữ dữ liệu và đá ra khỏi kết nối trong viewDidLoad; nó tập hợp các mảnh khi chúng đến trong didReceiveData; và connectionDidFinishLoading trống sẵn sàng làm điều gì đó với kết quả. Sử dụng Dữ liệu JSON

Tiếp theo, chúng tôi sẽ xác định phương thức connectionDidFinishLoading để tận dụng dữ liệu JSON được truy xuất trong bước cuối cùng.

Cập nhật phương pháp connectionDidFinishLoading:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    [connection release]; 

    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 
    [responseData release]; 

    NSArray *luckyNumbers = [responseString JSONValue]; 

    NSMutableString *text = [NSMutableString stringWithString:@"Lucky numbers:\n"]; 

    for (int i = 0; i < [luckyNumbers count]; i++) 
     [text appendFormat:@"%@\n", [luckyNumbers objectAtIndex:i]]; 

    label.text = text; 
} 

Nó tạo ra một NSArray. Trình phân tích cú pháp rất linh hoạt và trả về các đối tượng - bao gồm các đối tượng lồng nhau - phù hợp một cách thích hợp với các kiểu dữ liệu JSON đối với kiểu dữ liệu Objective-C. Xử lý lỗi tốt hơn

Cho đến nay, chúng tôi đã sử dụng tiện ích mở rộng cấp cao, tiện lợi cho phương pháp phân tích cú pháp JSON của NSString. Chúng tôi đã làm như vậy với lý do chính đáng: thật đơn giản để gửi thông điệp JSONValue đến một chuỗi để truy cập vào các giá trị JSON được phân tích cú pháp.

Thật không may, sử dụng phương pháp này làm cho việc xử lý lỗi hữu ích trở nên khó khăn. Nếu trình phân tích cú pháp JSON không thành công vì bất kỳ lý do gì, nó chỉ trả về giá trị nil. Tuy nhiên, nếu bạn xem nhật ký bảng điều khiển của mình khi điều này xảy ra, bạn sẽ thấy thông báo mô tả chính xác điều gì khiến trình phân tích cú pháp thất bại.

Thật tuyệt khi có thể chuyển các chi tiết lỗi đó cho người dùng. Để làm như vậy, chúng tôi sẽ chuyển sang phương thức hướng đối tượng thứ hai mà SDK JSON hỗ trợ.

Cập nhật phương pháp connectionDidFinishLoading trong:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    [connection release]; 

    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 
    [responseData release]; 

    NSError *error; 
    SBJSON *json = [[SBJSON new] autorelease]; 
    NSArray *luckyNumbers = [json objectWithString:responseString error:&error]; 
    [responseString release]; 

    if (luckyNumbers == nil) 
     label.text = [NSString stringWithFormat:@"JSON parsing failed: %@", [error localizedDescription]]; 
    else { 
     NSMutableString *text = [NSMutableString stringWithString:@"Lucky numbers:\n"]; 

     for (int i = 0; i < [luckyNumbers count]; i++) 
      [text appendFormat:@"%@\n", [viewcontroller objectAtIndex:i]]; 

     label.text = text; 
    } 
} 

Sử dụng phương pháp này cho chúng ta một con trỏ đến đối tượng lỗi của bộ phân tích JSON cơ bản mà chúng ta có thể sử dụng để xử lý lỗi hữu ích hơn.

Kết luận:

SDK JSON và hỗ trợ dựng sẵn của Cocoa cho HTTP giúp thêm các dịch vụ web JSON vào ứng dụng iPhone đơn giản.

+0

Tôi có định dạng json như thế này, làm cách nào tôi có thể sử dụng, hãy giúp tôi. jsont ({ "id": "ntp-a1.nict.go.jp", "nó": 1232963971,248, "st": 1344228610,961, "bước nhảy vọt": 34, "bên cạnh": 1341100800, " bước ": 1 }) –

0

Bây giờ, Mục tiêu c đã giới thiệu trong lớp xây dựng để phân tích cú pháp JSON.

NSError *myError = nil; 
NSDictionary *resultDictionary = [NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingMutableLeaves error:&myError]; 

http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html

Vì vậy, sử dụng lớp này và làm cho lỗi ứng dụng của bạn miễn phí ... :)

Các vấn đề liên quan