【问题标题】:Parse json with NSJSONSerialization class using objectForKey in iOS在 iOS 中使用 objectForKey 解析带有 NSJSONSerialization 类的 json
【发布时间】:2012-07-31 10:48:11
【问题描述】:

我是 iOS 开发的新手。我使用此代码连接到我的 REST Web 服务并以 Json 格式获取数据。

    NSString *url=@"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)

你能帮帮我吗?

【问题讨论】:

    标签: iphone objective-c ios ios5 nsjsonserialization


    【解决方案1】:

    你必须访问item数组的0项:

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

    当您收到此错误:-[__NSArrayM objectForKey:],您需要意识到您尝试访问的对象不是字典。它是一个数组 (__NSArrayM),所以您必须先访问 0 索引,然后再开始探索字典。

    查看 Ray Wenderlich 的 this 精彩教程,该教程解释了有关崩溃的所有内容。

    【讨论】:

      【解决方案2】:

      正如 Alberto 所说,您假设 item 是 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"]; 
      } 
      

      另一件有用的事情是,例如,如果您想获取所有“名称”值,可以在 items 数组上使用 valueForKey,它会自动为您在每个字典上调用 valueForKey。示例:

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

      【讨论】:

      • 感谢您的澄清。很有用。
      • @Ali 很高兴你发现它有用:)
      【解决方案3】:

      从错误和代码的日志输出来看,您似乎正在尝试在NSArray 上执行选择器objectForKey。 尝试将NSString *name = [item objectForKey:@"name"];改为NSString *name = [[item objectAtIndex: 0]objectForKey:@"name"];

      【讨论】:

        【解决方案4】:

        此代码可以帮助您从NSArray 获取第一个类型字典的对象

        [[jsonArray objectAtIndex:0]objectForKey:@"object-key"];
        

        【讨论】:

          【解决方案5】:
          -(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];
          }
          

          【讨论】:

            猜你喜欢
            • 2013-12-22
            • 1970-01-01
            • 2012-08-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多