【问题标题】:Objective C JSON parse from NSMutableArray来自 NSMutableArray 的 Objective C JSON 解析
【发布时间】:2017-08-03 09:03:51
【问题描述】:

我有一个如下所示的 JSON(从 URL 获取)-

{
action :getAllJournal;
data :{
    journalList :[{
            cancelled : F;
            "cust_code" : "700-T022";
            "journal_amount" : 2216;
            "journal_code" : "JV1603/001";
            "journal_date" : "2016-03-15 00:00:00";
            "journal_id" : 1;
            outstanding : 0;
        },
                    {
            cancelled : F;
            "cust_code" : "700-0380";
            "journal_amount" : 120;
            "journal_code" : "JV1605/006";
            "journal_date" : "2016-05-31 00:00:00";
            "journal_id" : 2;
            outstanding : 120;
        },
                    {
            cancelled : F;
            "cust_code" : "700-T280";
            "journal_amount" : 57;
            "journal_code" : "JV1609/001";
            "journal_date" : "2016-09-22 00:00:00";
            "journal_id" : 3;
            outstanding : 0;
        }
    ];
};
message = "";
"message_code" = "";
result = 1;}

下面的代码是从 URL 获取 JSON 并将它们存储在 NSMutableArray 中。在将它们存储到数组之前,它工作正常,但我对 JSON 格式有点困惑,不知道如何通过键获取结果。

__block NSMutableArray *jsonArray = nil;
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSString *urlString = [NSString stringWithFormat:@"http://xxxxxxx/api.php?action=getAllJournal"];
NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * response, NSData * data, NSError * connectionError)
 {
     if (data)
     {
         id myJSON;
         @try {
             myJSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
         }
         @catch (NSException *exception) {
         }
         @finally {
         }
         jsonArray = (NSMutableArray *)myJSON;

         NSString *nsstring = [jsonArray description];
         NSLog(@"IN STRING -> %@",nsstring);

         NSData *data = [nsstring dataUsingEncoding:NSUTF8StringEncoding];
         NSError *jsonError;
         NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
         if(jsonObject !=nil){

             if(![[jsonObject objectForKey:@"journalList"] isEqual:@""]){

                 NSMutableArray *array=[jsonObject objectForKey:@"journalList"];

                 NSLog(@"array: %lu",(unsigned long)array.count);

                 int k = 0;
                 for(int z = 0; z<array.count;z++){

                     NSString *strfd = [NSString stringWithFormat:@"%d",k];
                     NSDictionary *dicr = jsonObject[@"journalList"][strfd];
                     k=k+1;
                     // NSLog(@"dicr: %@",dicr);
                     NSLog(@"cust_code - journal_amount   : %@ - %@",
                           [NSMutableString stringWithFormat:@"%@",[dicr objectForKey:@"cust_code"]],
                           [NSMutableString stringWithFormat:@"%@",[dicr objectForKey:@"journal_amount"]]);
                 }

             }

         }else{
             NSLog(@"Error - %@",jsonError);
         }

     }
 }];

由此,我能够成功获取 JSON。但它总是给我这个错误:Error Domain=NSCocoaErrorDomain Code=3840 "No string key for value in an object around character 6." UserInfo={NSDebugDescription=No string key for value in an object around character 6.}如何从journalList获取所有值?我是 iOS 新手,这就是为什么不知道我错过了什么。

【问题讨论】:

  • 你可以为记者创建一个模型类,然后使用像github.com/stig/json-framework这样的库来帮助你轻松地将json解析为对象
  • 您的 JSON 无效。修复它在此处检查您的 json:jsonlint.com
  • @kapsym 我现在不愿意使用任何库..有没有可能的方法在不使用库的情况下做到这一点?
  • 可能是你的 json 序列化没有得到正确的 json 格式。你能准确地告诉你的代码在哪里得到这个错误。
  • NSString *nsstring = [jsonArray description]; NSLog(@"IN STRING -&gt; %@",nsstring); NSData *data = [nsstring dataUsingEncoding:NSUTF8StringEncoding]; No 和 No. NSArray *journalList = myJSON[@"data"][@"journalList"],这是一个字典数组。

标签: ios objective-c json


【解决方案1】:
id myJSON;
 @try {
     myJSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
 }
 @catch (NSException *exception) {
 }
 @finally {
 }
 jsonArray = (NSMutableArray *)myJSON;

 NSString *nsstring = [jsonArray description];
 NSLog(@"IN STRING -> %@",nsstring);

 NSData *data = [nsstring dataUsingEncoding:NSUTF8StringEncoding];
 NSError *jsonError;
 NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];

我会说:NONO

我不会对NSJSONSerialization 执行@try/@catch,因为真正的问题在于error 参数(在大多数情况下它们不会抛出NSException)。只需检查if (data) 是否非常有效。

然后,假设它有效,并且您拥有myJSON。 事实上,myJSONNSDictionary,而不是 NSArray,所以演员表没用,没有意义。

下一期: 你正在使用-description(好吧,如果你想调试),但你不能用它来重建一个JSON。它不是一个有效的 JSON,它是编译器“打印”对象的方式,它添加了“;”等。 如果您的打印 [nsstring dataUsingEncoding:NSUTF8StringEncoding]data 您会发现它们不一样。 为了更具可读性: NSString *dataJSONStr = [[NSString alloc] initWithData:data encoding: NSUTF8StringEncoding];,显然和你的nsstring的结构不一样。

那么,你是在重做 JSON 序列化吗?为什么?

所以:

NSError *errorJSON = nil;
NSDictionary *myJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&errorJSON];
if (errorJSON)
{
    NSLog(@"Oops error JSON: %@", errorJSON);
}
NSDictionary *data = myJSON[@"data"];
NSArray *journalList = data[@"journalList"]
for (NSDictionary *aJournalDict in journalList)
{
    NSUInteger amount = [aJournalDict[@"journal_amount"] integerValue];
    NSString *code = aJournalDict[@"journal_code"];
}

【讨论】:

    【解决方案2】:

    您没有获取一个名为“数据”的字典,由 {} 表示。

    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
    
    if (!jsonError) {
    
        // Fetch the journalList
        NSArray *journalList = json[@"data"][@"journalList"];
    
        // iterate over every entry and output the wanted values
        for (NSDictionary *journal in journalList) {
            NSLog(@"%@ %@", journal[@"cust_code"], journal[@"journal_amount"]);
        }
    }
    

    json[@"key"] 是 [json objectForKey:@"key"] 的缩写形式,我觉得更容易阅读。

    【讨论】:

    • 你的方法是正确的。我已经发布了正确的答案并提到了你的名字以获得信用;)
    【解决方案3】:

    这不是一个有效的 JSON。条目应该用逗号分隔,,而不是分号;

    【讨论】:

    • 我从控制台复制了它,这可能就是为什么显示 ; .. 但在 API 中,它显示的是 ,
    • 当然是web API中的字符串。你打印的是不是 JSON。
    【解决方案4】:

    你需要从data获取journalList

    试试下面的代码:

    这是创建像你一样的数组的演示代码:

    NSMutableDictionary *jsonObject = [NSMutableDictionary new];
    jsonObject[@"action"]= @"";
    jsonObject[@"message"]= @"";
    jsonObject[@"message_code"]= @"";
    jsonObject[@"result"]= @"1";
    NSMutableArray *ary1 = [NSMutableArray new];
    for(int i=0;i<5;i++)
    {
        NSMutableDictionary *dd = [NSMutableDictionary new];
        dd[@"cancelled"]= @"F";
        dd[@"cust_code"]= @"F";
        [ary1 addObject:dd];
    }
    
    
    NSMutableDictionary *dicjournal = [NSMutableDictionary new];
    [dicjournal setObject:ary1 forKey:@"journalList"];
    [jsonObject setObject:dicjournal forKey:@"data"];
    

    这是主逻辑:

    NSMutableArray *journalList = [NSMutableArray new];
    NSMutableDictionary *dic = [jsonObject valueForKey:@"data"];
    journalList = [[dic objectForKey:@"journalList"] mutableCopy];
    

    【讨论】:

    • 我收到此错误Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArray0 objectForKey:]: unrecognized selector sent to instance 0x145487b0
    • 给我 2 分钟。让我创建一个 JSON 对象并为您提供解决方案。
    • 我创建了类似的数组并填充了 journalList 值。
    • json 是无效的,你如何创建数据然后
    • @Vinodh 您可以打印“jsonObject”对象并进行比较。
    【解决方案5】:

    看起来您的 JSON 无效。您可以使用http://jsonviewer.stack.hu/ 查看您的 JSON 是否正确,并对其进行格式化。同时您的代码没有使用“data”键来获取“journalList”数组。

    代码:-

    NSDictionary *dic = [jsonObject valueForKey:@"data"];
    
    NSMutableArray *arr = [dic objectForKey:@"journalList"];
    
    for (int index=0 ; index < arr.count ; index++){
    
    NSDictionary *obj = [arr objectAtIndex:index];
    
    // Now use object for key from this obj to get particular key 
    
    }
    

    【讨论】:

      【解决方案6】:

      感谢@Larme 和@Amset 的帮助。我在NSMutableArray 部分做错了。该代码的正确版本如下:

      [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
      NSString *urlString = [NSString stringWithFormat:@"http://xxxxxxx/api.php?action=getAllJournal"];
      NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
      [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * response, NSData * data, NSError * connectionError)
       {
           if (data)
           {
               id myJSON;
               @try {
                   myJSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
               }
               @catch (NSException *exception) {
               }
               @finally {
               }
      
               NSArray *journalList = myJSON[@"data"][@"journalList"];
               for (NSDictionary *journal in journalList) {
                   NSLog(@"%@ %@", journal[@"journal_date"], journal[@"journal_amount"]);
               }
           }
       }];
      

      【讨论】:

      • 接受答案,让别人知道你遇到了什么问题
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多