Json没有根元素ios

时间:2013-04-04 15:49:18

标签: iphone ios objective-c json

所以我对ios开发很新,我正在创建我的第一个应用程序连接到服务器并提取一些信息。我已经遵循了许多不同的教程,并设法从不同的地方撤回一些json。我遇到的问题是我需要提取的信息没有根元素,我需要更改什么来获取信息到我的应用程序?

以下是我正在使用的代码:

   #import "leagueTableViewController.h"

   #define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

    #define kjsonURL [NSURL URLWithString: @"http://api.kivaws.org/v1/loans/search.json?status=fundraising"]
     @interface leagueTableViewController ()

      @end

      @implementation leagueTableViewController{

    NSMutableArray *jsonResults;
     }

    - (id)initWithStyle:(UITableViewStyle)style
    {
    self = [super initWithStyle:style];
     if (self) {
    // Custom initialization
     }
      return self;
        }

      - (void)viewDidLoad
       {
      [super viewDidLoad];

        dispatch_async(kBgQueue, ^{

           NSData* data = [NSData dataWithContentsOfURL:

                    kjsonURL];

          [self performSelectorOnMainThread:@selector(fetchedData:)

                           withObject:data waitUntilDone:YES];

             });
           }




        - (void)fetchedData:(NSData *)responseData {

           NSError* error;

           NSDictionary* json = [NSJSONSerialization

                      JSONObjectWithData:responseData

                      options:kNilOptions

                      error:&error];

       jsonResults = [json objectForKey:@"loans"];

       [self.tableView reloadData];

        }


    - (void)didReceiveMemoryWarning
      {
      [super didReceiveMemoryWarning];
       // Dispose of any resources that can be recreated.
        }

      #pragma mark - Table view data source

      - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
        {

      // Return the number of sections.
       return 1;
       }   

  - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:   (NSInteger)section
   {
   return [jsonResults count];
  }

      - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:  (NSIndexPath *)indexPath

       {
      static NSString *CellIdentifier = @"Cell";

       UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        NSDictionary *appsdict = [jsonResults objectAtIndex:indexPath.row];

       NSString *VersionString = [appsdict objectForKey:@"funded_amount"];

       NSString *priceString = [appsdict objectForKey:@"loan_amount"];


       cell.textLabel.text = [appsdict objectForKey:@"name"];

      cell.detailTextLabel.text = [NSString stringWithFormat:@"Version: %@ Price: $ %@ USD",VersionString,priceString];



     return cell;


     }

       #pragma mark - Table view delegate

      - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath   *)indexPath
     {
     //    NSDictionary *appsdict = [jsonResults objectAtIndex:indexPath.row];
     //    
    //    NSString *appURL = [appsdict objectForKey:@"trackViewUrl"];
     //    
    //    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:appURL]];
     }

    @end

这是上面代码使用的json的一个示例,因为您可以看到根元素:

      {
       "paging": {
      "page": 1,
      "total": 873,
      "page_size": 20,
       "pages": 44
        },
       "loans": [{
        "id": 544449,
        "name": "Sajad",
        "description": {
            "languages": ["en"]
          },
          "status": "fundraising",
          "funded_amount": 0,
          "basket_amount": 0,
          "image": {
            "id": 1325179,
            "template_id": 1
           },
          "activity": "Cloth & Dressmaking Supplies",
          "sector": "Retail",
           "use": "to renovate his shop and increase his textile inventory",
           "location": {
            "country_code": "IQ",
            "country": "Iraq",
            "geo": {
                "level": "country",
                "pairs": "33 44",
                "type": "point"
            }
           },
           "partner_id": 166,
          "posted_date": "2013-04-04T15:40:01Z",
           "planned_expiration_date": "2013-05-04T15:40:01Z",
           "loan_amount": 2400,
           "borrower_count": 1
            }

这是我需要获得的json,但它没有根元素,我需要做什么才能在我的应用中显示:

     [{
    "position": 1,
    "team_id": 10260,
    "team": "Manchester United",
    "teamshort": "Man Utd",
    "played": 30,
    "won": 25,
    "drawn": 2,
    "lost": 3,
    "for": 70,
    "against": 31,
    "difference": 39,
    "home": {
        "played": 15,
        "won": 14,
        "drawn": 0,
        "lost": 1,
        "for": 39,
        "against": 15,
        "difference": 24
    },
    "away": {
        "played": 15,
        "won": 11,
        "drawn": 2,
        "lost": 2,
        "for": 31,
        "against": 16,
        "difference": 15
    },
    "points": 77,
    "info": "championsleague"
}

3 个答案:

答案 0 :(得分:1)

使用JSON,您需要事先知道结构。发送数据的API会让您知道这一点。

您收到错误的原因是由于您正在将NSArray视为NSDictionary。这是一个例子。

这应解析为NSArray:

[{
    username: 'johndoe'
}]

这将是NSDictioanry:

{
   username: 'johndoe'
}

您拥有的数据类似于我提出的第一个案例。因此,要获取数据,您需要以下内容:

NSArray* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];

[[json objectAtIndex: 0] objectForKey:@"thekey"]

答案 1 :(得分:0)

如果在尝试阅读第一个括号之前,第二个块将正确解析:

NSData *strippedData = [data subdataWithRange:NSMakeRange(1, data.length-1)];

就你所收到的错误而言,这不是NSJSONSerialization错误,而是说返回的对象是NSArray类型(即使你期望NSDictionary类型)并且你试图调用{{ 1}},它不是NSArray的方法。您应该分析数组并查看它是否包含您需要的信息。这可能看起来像这样:

objectForKey:
祝你好运。

答案 2 :(得分:0)

“没有根元素”的第二个响应是无效的JSON 。这就是无法解析的原因。没有没有根元素的JSON这样的东西 - 只有有效的JSON和破坏的无效JSON。你有几个选择:

  1. 正如@daltonclaybrook建议的那样,剥离出领先的“[”。或者,最后添加一个额外的“]”。任何更改都将导致有效的JSON。我不喜欢这种方法,因为如果服务器给你破坏的JSON,那么它可能不会一直被破坏,或者它们可能会在某些时候修复它。

  2. 在服务器端修复JSON 。如果您与服务器有任何连接,请告诉他们他们的JSON已损坏并让他们修复它。如果您无法解决问题,我表示哀悼,因为处理搞砸的服务器根本不是一件好事。如果有可能解决问题,那样做而不是试图弄清楚这次如何破坏并将其修复到最后。