2012-07-31 25 views
5

我是iOS開發新手。我使用此代碼連接到我的REST Web服務並以Json格式獲取數據。在iOS中使用objectForKey解析json與NSJSONSerialization類

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

現在我想通過objectForKey分開它們。我在循環中使用了這段代碼:

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

它不起作用。我得到這個錯誤:

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) 

你能幫助我嗎?

回答

2

您有權訪問item陣列的0項目:

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

當你得到這個錯誤:-[__NSArrayM objectForKey:],你需要認識到,你要訪問的對象不是一本字典。它是一個數組(__NSArrayM),所以您必須先訪問0索引,然後開始瀏覽字典。

看看Ray Wenderlich的一個神奇的教程this,它解釋了關於崩潰的所有信息。

0

從您的代碼的錯誤和日誌輸出它看起來像你試圖在NSArray上執行objectForKey選擇器。 嘗試改變NSString *name = [item objectForKey:@"name"];NSString *name = [[item objectAtIndex: 0]objectForKey:@"name"];

2

正如阿爾貝託說,您認爲該項目是一個NSDictionary,而在現實中是包含多個字典的NSArray。現在下鑽部分可以使用valueForKeyPath,如下所示。所以,你的for循環應該是這樣的:

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

知道另一個有用的事情是,如果你想獲得例如所有的「名」的價值觀,你可以在你的項目陣列上使用valueForKey,這將自動爲每個字典撥打valueForKey。例如:

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

我很欣賞你的澄清獲得型詞典的第一個對象。這很有用。 – Ali 2012-07-31 11:53:37

+0

@Ali很高興你發現它有用:) – Alladinian 2012-07-31 11:54:07

0

可能這個代碼幫助您從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]; 
}