1

所以我对 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"
}
4

3 回答 3

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"]
于 2013-04-04T17:08:42.373 回答
0

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

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

就您收到的错误而言,这不是 NSJSONSerialization 错误,它表示返回的对象是 NSArray 类型(即使您期待 NSDictionary 类型)并且您正在尝试调用objectForKey:它,即不是 NSArray 的方法。您应该分析数组,看看它是否包含您需要的信息。这可能看起来像这样:

NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonError];
jsonResults = [[jsonArray objectAtIndex:0] objectForKey:@"loans"];

祝你好运。

于 2013-04-04T16:16:39.800 回答
0

“没有根元素”的第二个响应不是有效的 JSON。这就是它无法解析的原因。没有没有根元素的 JSON 之类的东西——只有有效的 JSON 和损坏的无效 JSON。你有几个选择:

  1. 正如@daltonclaybrook 建议的那样,去掉前导的“[”。或者,在末尾添加一个额外的“]”。任何一种更改都会产生有效的 JSON。我不喜欢这种方法,因为如果服务器给你提供了损坏的 JSON,那么它可能不会一直被损坏,或者他们可能会在某个时候修复它。

  2. 修复服务器端的 JSON。如果您与服务器有任何连接,请告诉他们他们的 JSON 已损坏并让他们修复它。如果你不能把它修好,我的哀悼,因为处理搞砸的服务器一点也不好玩。如果有任何可能解决这个问题,那就去做吧,而不是试图弄清楚这次是怎么坏的,然后再把它修好。

于 2013-04-04T16:34:13.470 回答