2012-07-31 47 views
5

Tôi mới phát triển iOS. Tôi sử dụng mã này để kết nối với Dịch vụ Web REST của tôi và tìm nạp dữ liệu ở định dạng Json.Phân tích cú pháp json với lớp NSJSONSerialization bằng cách sử dụng objectForKey trong iOS

NSString *[email protected]"URL_Address"; 

    NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url]]; 

    NSURLResponse *resp = nil; 
    NSError *err = nil; 

    NSData *response = [NSURLConnection sendSynchronousRequest: theRequest returningResponse: &resp error: &err]; 

// NSString * theString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding]; 
// NSLog(@"response: %@", theString); 

    NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData: response options: NSJSONReadingMutableContainers error: &err]; 

    if (!jsonArray) { 
     NSLog(@"Error parsing JSON: %@", err); 
    } else { 
     for(NSDictionary *item in jsonArray) { 
      NSLog(@" %@", item); 
      NSLog(@"---------------------------------"); 
     } 
    } 

Bây giờ tôi muốn tách riêng chúng qua objectForKey. Tôi đã sử dụng mã này bên trong vòng lặp:

NSString *name = [item objectForKey:@"name"]; 

Nó không hoạt động. Tôi gặp lỗi này:

2012-07-31 12:48:38.426 LearningAFNetworking[390:f803] -[__NSArrayM objectForKey:]: unrecognized selector sent to instance 0x6844460 
2012-07-31 12:48:38.428 LearningAFNetworking[390:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM objectForKey:]: unrecognized selector sent to instance 0x6844460' 
*** First throw call stack: 
(0x13c8022 0x1559cd6 0x13c9cbd 0x132eed0 0x132ecb2 0x2f40 0x2bf8 0xd9a1e 0x38401 0x38670 0x38836 0x3f72a 0x290b 0x10386 0x11274 0x20183 0x20c38 0x14634 0x12b2ef5 0x139c195 0x1300ff2 0x12ff8da 0x12fed84 0x12fec9b 0x10c65 0x12626 0x254d 0x24b5 0x1) 
terminate called throwing an exception(lldb) 

bạn có thể giúp tôi không?

Trả lời

2

Bạn phải truy cập vào 0 mục của item mảng:

NSArray *mainArray = [item objectAtIndex:0]; 
(NSDictionary *obj in mainArray) { 
    NSString *name = [obj objectForKey:@"name"]; 
} 

Khi bạn gặp lỗi này: -[__NSArrayM objectForKey:], bạn cần phải nhận ra rằng các đối tượng mà bạn đang cố gắng truy cập không phải là một cuốn từ điển. Đó là một mảng (__NSArrayM), vì vậy trước tiên bạn phải truy cập vào chỉ mục 0 và sau đó bắt đầu khám phá từ điển.

Hãy xem this hướng dẫn tuyệt vời, từ Ray Wenderlich, giải thích mọi thứ về sự cố.

0

Từ lỗi và từ đầu ra nhật ký mã của bạn, có vẻ như bạn đang cố thực hiện công cụ chọn objectForKey trên NSArray. Cố gắng thay đổi NSString *name = [item objectForKey:@"name"];-NSString *name = [[item objectAtIndex: 0]objectForKey:@"name"];

2

Như Alberto cho biết, bạn cho rằng mục mà là một NSDictionary trong khi trên thực tế là một NSArray chứa nhiều từ điển. Bây giờ cho phần khoan xuống, bạn có thể sử dụng valueForKeyPath như được hiển thị bên dưới. Vì vậy, for vòng lặp của bạn nên có một cái gì đó như thế này:

NSArray *items = [jsonArray objectAtIndex:0]; 

for (NSDictionary *item in items){ 
    NSString *name = [item valueForKey:@"name"]; 
    // You can also get nested properties like this 
    NSString *projectName = [item valueForKeyPath:@"project.name"]; 
} 

Một điều hữu ích để biết là nếu bạn muốn có được tất cả 'tên' giá trị ví dụ, bạn có thể sử dụng valueForKey trên mảng các mục của bạn, mà sẽ tự động gọi valueForKey trên mỗi từ điển cho bạn. Ví dụ:

NSArray *items = [jsonArray objectAtIndex:0]; 
NSArray *names = [items valueForkey:@"name"]; 
+0

Tôi đánh giá cao để làm rõ của bạn. Nó rất hữu ích. – Ali

+0

@Ali Rất vui khi bạn thấy nó hữu ích :) – Alladinian

0

May mã này giúp bạn để có được những đối tượng đầu tiên của từ điển loại từ NSArray

[[jsonArray objectAtIndex:0]objectForKey:@"object-key"]; 
0
-(void)clientServerCommunication 
{ 
    NSURL *url = [NSURL URLWithString:@"http://182.72.122.106/iphonetest/getTheData.php"]; 
    NSURLRequest *req = [NSURLRequest requestWithURL:url]; 
    NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:req delegate:self]; 
    if (connection) 
    { 
     webData = [[NSMutableData alloc]init]; 
    } 
} 
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{ 
    [webData setLength:0]; 
} 

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

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:webData options:0 error:nil]; 

    /*Third party API 
    NSString *respStr = [[NSString alloc]initWithData:webData encoding:NSUTF8StringEncoding]; 
    SBJsonParser *objSBJson = [[SBJsonParser alloc]init]; 
    NSDictionary *responseDict = [objSBJson objectWithString:respStr]; */ 
    resultArray = [[NSArray alloc]initWithArray:[responseDict valueForKey:@"result"]]; 
    NSLog(@"resultArray: %@",resultArray); 
    [self.tableView reloadData]; 
} 
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 
    custcell=[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 



    if(custcell==nil) 
    { 

     custcell=[[[NSBundle mainBundle]loadNibNamed:@"custumCell" owner:self options:nil]objectAtIndex:0]; 

    } 


    custcell.persnName.text=[[arr objectAtIndex:indexPath.row]valueForKey:@"Name"]; 
    //else if (objsegment.selectedSegmentIndex==1) 
    //{ 
    custcell.persnAge.text=[[arr objectAtIndex:indexPath.row]valueForKey:@"Age"]; 

    [sortcontrol addTarget:self action:@selector(SegmentbtnCLK:) forControlEvents:UIControlEventValueChanged]; 

    //objsegment.selectedSegmentIndex=0; 
    // } 

    return custcell; 
} 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // Navigation logic may go here, for example: 
    //Create the next view controller. 
    detailViewController *detailViewController1 = [[detailViewController alloc]initWithNibName:@"detailViewController" bundle:nil]; 

//detailViewController *detailViewController = [[detailViewController alloc] initWithNibName:@"detailViewController" bundle:nil]; 

// Pass the selected object to the new view controller. 

// Push the view controller. 
detailViewController1.nextDict = [[NSDictionary alloc]initWithDictionary:[resultArray objectAtIndex:indexPath.row]]; 
[self.navigationController pushViewController:detailViewController1 animated:YES]; 

    // Pass the selected object to the new view controller. 

    // Push the view controller. 
    // [self.navigationController pushViewController:detailViewController animated:YES]; 
} 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view from its nib. 
    empName.text=[nextDict valueForKey:@"name"]; 
    deptlbl.text=[nextDict valueForKey:@"department"]; 
    designationLbl.text=[nextDict valueForKey:@"designation"]; 
    idLbl.text=[nextDict valueForKey:@"id"]; 
    salaryLbl.text=[nextDict valueForKey:@"salary"]; 
    NSString *ImageURL = [nextDict valueForKey:@"image"]; 
    NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]]; 
    image.image = [UIImage imageWithData:imageData]; 
} 
Các vấn đề liên quan