【问题标题】:JSON Parsing in iOS 7iOS 7 中的 JSON 解析
【发布时间】:2013-10-24 14:54:36
【问题描述】:

我正在为现有网站创建一个应用程序。他们目前的 JSON 格式如下:

[

   {
       "id": "value",
       "array": "[{\"id\" : \"value\"} , {\"id\" : \"value\"}]"
   },
   {
       "id": "value",
       "array": "[{\"id\" : \"value\"},{\"id\" : \"value\"}]"
   } 
]

他们在使用 Javascript 转义 \ 字符后对其进行解析。

我的问题是当我在 iOS 中使用以下命令解析它时:

NSArray *result = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&localError];

然后这样做:

NSArray *Array = [result valueForKey:@"array"];

我得到的是NSMutableString 对象,而不是Array

  • 该网站已经在生产中,所以我不能要求他们更改现有结构以返回正确的 JSON 对象。这对他们来说将是很多工作。

  • 那么,在他们改变底层结构之前,我有什么办法可以让它在iOS 中工作,就像他们在website 上使用javascript 一样?

任何帮助/建议都会对我很有帮助。

【问题讨论】:

  • 能否提供网络服务链接?
  • “数组”值一个字符串,而不是一个数组。这是因为它全部被引用和转义。要访问其中的值,您需要在将字符串转换为 NSData 之后再次通过 JSONObjectWithData 运行它。 (YOY NSJONSerialization 没有接受字符串的方法吗??)
  • 感谢@HotLicks。不,NSJSONSerialization 只接受数据或流。
  • @Ajeet -- 仅供参考,“YOY 是一种悲哀——“为什么哦为什么”。
  • 对不起..我没明白.. :D

标签: ios objective-c json nsmutablearray nsarray


【解决方案1】:

正确的 JSON 应该类似于:

[
    {
        "id": "value",
        "array": [{"id": "value"},{"id": "value"}]
    },
    {
        "id": "value",
        "array": [{"id": "value"},{"id": "value"}]
    }
]

但是,如果您遇到问题中提供的格式,您需要使用NSJSONReadingMutableContainers 使字典可变,然后为每个array 条目再次调用NSJSONSerialization

NSMutableArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
if (error)
    NSLog(@"JSONObjectWithData error: %@", error);

for (NSMutableDictionary *dictionary in array)
{
    NSString *arrayString = dictionary[@"array"];
    if (arrayString)
    {
        NSData *data = [arrayString dataUsingEncoding:NSUTF8StringEncoding];
        NSError *error = nil;
        dictionary[@"array"] = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
        if (error)
            NSLog(@"JSONObjectWithData for array error: %@", error);
    }
}

【讨论】:

【解决方案2】:

试试这个简单的方法....

- (void)simpleJsonParsing
{
    //-- Make URL request with server
    NSHTTPURLResponse *response = nil;
    NSString *jsonUrlString = [NSString stringWithFormat:@"http://domain/url_link"];
    NSURL *url = [NSURL URLWithString:[jsonUrlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    //-- Get request and response though URL
    NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];

    //-- JSON Parsing
    NSMutableArray *result = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
    NSLog(@"Result = %@",result);

    for (NSMutableDictionary *dic in result)
    {
         NSString *string = dic[@"array"];
        if (string)
        {
             NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
             dic[@"array"] = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        }
        else
        {
             NSLog(@"Error in url response");
        }
    }

}

【讨论】:

    【解决方案3】:

    正如上面所说的,您必须首先使用NSJSONSerializationJSON 反序列化为可用的数据结构,如NSDictionaryNSArray

    但是,如果您想将 JSON 的内容映射到您的 Objective-C 对象,您必须将每个属性从 NSDictionary/NSArray 映射到您的对象属性。如果你的对象有很多属性,这可能会有点痛苦。

    为了使流程自动化,我建议您使用NSObject(个人项目)上的Motis 类别来完成它,因此它非常轻量级和灵活。您可以在this post 中阅读如何使用它。但只是为了向您展示,您只需定义一个字典,将您的 JSON 对象属性映射到您的 NSObject 子类中的 Objective-C 对象属性名称:

    - (NSDictionary*)mjz_motisMapping
    {
        return @{@"json_attribute_key_1" : @"class_property_name_1",
                 @"json_attribute_key_2" : @"class_property_name_2",
                  ...
                 @"json_attribute_key_N" : @"class_property_name_N",
                };
    }
    

    然后执行解析:

    - (void)parseTest
    {
        // Some JSON object
        NSDictionary *jsonObject = [...];
    
        // Creating an instance of your class
        MyClass instance = [[MyClass alloc] init];
    
        // Parsing and setting the values of the JSON object
        [instance mjz_setValuesForKeysWithDictionary:jsonObject];
    }
    

    字典中的属性设置是通过KeyValueCoding (KVC) 完成的,您可以在通过KVC 验证设置之前验证每个属性。

    希望它对你的帮助和对我的帮助一样多。

    【讨论】:

      【解决方案4】:
      //-------------- get data url--------
      
      NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://echo.jsontest.com/key/value"]];
      
      NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
      NSLog(@"response==%@",response);
      NSLog(@"error==%@",Error);
      NSError *error;
      
      id jsonobject=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
      
      if ([jsonobject isKindOfClass:[NSDictionary class]]) {
          NSDictionary *dict=(NSDictionary *)jsonobject;
          NSLog(@"dict==%@",dict);
      }
      else
      {
          NSArray *array=(NSArray *)jsonobject;
          NSLog(@"array==%@",array);
      }
      

      【讨论】:

        【解决方案5】:

        // ----------------- 本地文件的 json------------------------- --

        NSString *pathofjson = [[NSBundle mainBundle]pathForResource:@"test1" ofType:@"json"];
        NSData *dataforjson = [[NSData alloc]initWithContentsOfFile:pathofjson];
        arrayforjson = [NSJSONSerialization JSONObjectWithData:dataforjson options:NSJSONReadingMutableContainers error:nil];
        [tableview reloadData];
        

        //------------- urlfile的json----------------------------- ------

        NSString *urlstrng = @"http://www.json-generator.com/api/json/get/ctILPMfuPS?indent=4";
        NSURL *urlname = [NSURL URLWithString:urlstrng];
        NSURLRequest *rqsturl = [NSURLRequest requestWithURL:urlname];
        

        //------------ json for urlfile by asynchronous------------------------

        [NSURLConnection sendAsynchronousRequest:rqsturl queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            arrayforjson = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
            [tableview reloadData];
        }];
        

        //------------- urlfile的json同步----------

        NSError *error;
        NSData *data = [NSURLConnection sendSynchronousRequest:rqsturl returningResponse:nil error:&error];
        
         arrayforjson = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
        
        [tableview reloadData];
        } ;
        

        【讨论】:

          【解决方案6】:
          • 在将jsonData 发送给NSJSONSerialization 之前,您始终可以取消转义。或者您可以使用字符串 got 构造另一个 json object 来获取 array

          • NSJSONSerialization 做得对,你的例子中的值应该是一个字符串。

          【讨论】:

          • 在第一次解码之前取消转义很棘手,因为还必须删除周围的引号。
          • @HotLicks 更糟糕的是,value 字符串内可能存在合法转义的引号,无论是在 array 值内还是在更高级别的 value 内。
          • @Rob - 正确。如果已知 JSON 以可以避免此类问题的方式受到“约束”,则“取消转义”只会是一半安全的。
          【解决方案7】:

          正如另一个答案所说,该值是一个字符串。

          您可以通过将该字符串转换为数据来绕过它,因为它似乎是一个有效的 json 字符串,然后将该 json 数据对象解析回一个数组,您可以将该数组作为键的值添加到您的字典中。

          【讨论】:

          • @Lefteris - 将 what 视为 JSON 数组?这是一个 JSON 数组:[{"id": "value"},{"id": "value"}]。这是一个字符串:"[{\"id\" : \"value\"},{\"id\" : \"value\"}]".
          【解决方案8】:
           NSError *err;
              NSURL *url=[NSURL URLWithString:@"your url"];
              NSURLRequest *req=[NSURLRequest requestWithURL:url];
              NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:nil error:&err];
              NSDictionary *json=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
              NSArray * serverData=[[NSArray alloc]init];
              serverData=[json valueForKeyPath:@"result"];
          

          【讨论】:

            【解决方案9】:
            NSString *post=[[NSString stringWithFormat:@"command=%@&username=%@&password=%@",@"login",@"username",@"password"]stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
            
                NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.blablabla.com"]];
            
               [request setHTTPMethod:@"POST"];
            
               [request setValue:@"x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
                [request setHTTPBody:[NSData dataWithBytes:[post UTF8String] length:strlen([post UTF8String])]];
            
               NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
            
                id jsonobject=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
            
                if ([jsonobject isKindOfClass:[NSDictionary class]])
                {
            
                    NSDictionary *dict=(NSDictionary *)jsonobject;
                    NSLog(@"dict==%@",dict);
            
                }
                else
                {
            
                    NSArray *array=(NSArray *)jsonobject;
                    NSLog(@"array==%@",array);
                }
            

            【讨论】:

              【解决方案10】:

              也许这会对你有所帮助。

              - (void)jsonMethod
              {
                  NSMutableArray *idArray = [[NSMutableArray alloc]init];
                  NSMutableArray *nameArray = [[NSMutableArray alloc]init];
                  NSMutableArray* descriptionArray = [[NSMutableArray alloc]init];
              
                  NSHTTPURLResponse *response = nil;
                  NSString *jsonUrlString = [NSString stringWithFormat:@"Enter your URL"];
                  NSURL *url = [NSURL URLWithString:[jsonUrlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
              
              
                  NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
                  NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
              
                  NSDictionary *result = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:nil];
                  NSLog(@"Result = %@",result);
              
              
                  for (NSDictionary *dic in [result valueForKey:@"date"])
                  {
                      [idArray addObject:[dic valueForKey:@"key"]];
                      [nameArray addObject:[dic valueForKey:@"key"]];
                      [descriptionArray addObject:[dic valueForKey:@"key"]];
              
                  }
              
              }
              

              【讨论】:

                【解决方案11】:

                JSON 默认方法:

                + (NSDictionary *)stringWithUrl:(NSURL *)url postData:(NSData *)postData httpMethod:(NSString *)method
                {
                    NSDictionary *returnResponse=[[NSDictionary alloc]init];
                
                    @try
                    {
                        NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url
                                                                                  cachePolicy:NSURLRequestReloadIgnoringCacheData
                                                                              timeoutInterval:180];
                        [urlRequest setHTTPMethod:method];
                
                        if(postData != nil)
                        {
                            [urlRequest setHTTPBody:postData];
                        }
                
                        [urlRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
                        [urlRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
                        [urlRequest setValue:@"text/html" forHTTPHeaderField:@"Accept"];
                
                        NSData *urlData;
                        NSURLResponse *response;
                        NSError *error;
                        urlData = [NSURLConnection sendSynchronousRequest:urlRequest
                                                        returningResponse:&response
                                                                    error:&error];
                        returnResponse = [NSJSONSerialization
                                          JSONObjectWithData:urlData
                                          options:kNilOptions
                                          error:&error];
                    }
                    @catch (NSException *exception)
                    {
                        returnResponse=nil;
                    }
                    @finally
                    {
                        return returnResponse;
                    }
                }
                

                返回方法:

                +(NSDictionary *)methodName:(NSString*)string{
                    NSDictionary *returnResponse;
                    NSData *postData = [NSData dataWithBytes:[string UTF8String] length:[string length]];
                    NSString *urlString = @"https//:..url....";
                    returnResponse=[self stringWithUrl:[NSURL URLWithString:urlString] postData:postData httpMethod:@"POST"];    
                    return returnResponse;
                }
                

                【讨论】:

                  【解决方案12】:

                  @property NSMutableURLRequest * urlReq;

                  @property NSURLSession * 会话;

                  @property NSURLSessionDataTask * dataTask;

                  @property NSURLSessionConfiguration * sessionConfig;

                  @property NSMutableDictionary * appData;

                  @property NSMutableArray * valueArray; @property NSMutableArray * keysArray;

                  • (void)viewDidLoad { [超级视图DidLoad]; self.valueArray = [[NSMutableArray alloc]init]; self.keysArray = [[NSMutableArray alloc]init]; self.linkString = @"http://country.io/names.json"; [自我获取数据];

                  -(void)getData
                  { self.urlReq = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:self.linkString]];

                  self.sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
                  
                  self.session = [NSURLSession sessionWithConfiguration:self.sessionConfig];
                  
                  self.dataTask = [self.session dataTaskWithRequest:self.urlReq completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                      self.appData = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
                  
                      NSLog(@"%@",self.appData);
                      self.valueArray=[self.appData allValues];
                      self.keysArray = [self.appData allKeys];
                  
                  
                  }];
                  [self.dataTask resume];
                  

                  【讨论】:

                    【解决方案13】:
                    #define FAVORITE_BIKE @"user_id=%@&bike_id=%@"
                    @define FAVORITE_BIKE @"{\"user_id\":\"%@\",\"bike_id\":\"%@\"}"
                    NSString *urlString = [NSString stringWithFormat:@"url here"];
                    NSString *jsonString = [NSString stringWithFormat:FAVORITE_BIKE,user_id,_idStr];
                    NSData *myJSONData =[jsonString dataUsingEncoding:NSUTF8StringEncoding];
                    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
                    [request setURL:[NSURL URLWithString:urlString]];
                    [request setHTTPMethod:@"POST"];
                    NSMutableData *body = [NSMutableData data];
                    [body appendData:[NSData dataWithData:myJSONData]];
                    [request setHTTPBody:body];
                    NSError *error;
                    NSURLResponse *response;
                    NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
                    NSString *str = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
                    if(str.length > 0)
                    {
                        NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
                        NSMutableDictionary *resDict =[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
                    }
                    

                    【讨论】:

                      【解决方案14】:
                      -(void)responsedata
                      {
                      
                          NSMutableURLRequest *request=[[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:replacedstring]];
                      
                          [request setHTTPMethod:@"GET"];
                          NSURLSessionConfiguration *config=[NSURLSessionConfiguration defaultSessionConfiguration];
                          NSURLSession *session=[NSURLSession sessionWithConfiguration:config];
                          NSURLSessionDataTask *datatask=[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                              if (error) {
                                  NSLog(@"ERROR OCCURE:%@",error.description);
                              }
                              else
                              {
                                  NSError *error;
                                  NSMutableDictionary *responseDict=[[NSMutableDictionary alloc]init];
                                  responseDict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
                      
                      
                                  if (error==nil)
                                  {
                      
                      
                                   // use your own array or dict for fetching as per your key..  
                      
                      
                                      _responseArray =[[NSMutableArray alloc]init];
                      
                                      _geometryArray=[[NSMutableArray alloc]init];
                      
                      
                      
                                      _responseArray=[responseDict valueForKeyPath:@"result"];
                      
                                      referncestring =[[_photosArray objectAtIndex:0]valueForKey:@"photo_reference"];
                      
                                      _geometryArray=[_responseArray valueForKey:@"geometry"];
                                     // _locationArray=[[_geometryArray objectAtIndex:0]valueForKey:@"location"];
                                      _locationArray=[_geometryArray valueForKey:@"location"];
                                      latstring=[_locationArray valueForKey:@"lat"];
                                      lngstring=[_locationArray valueForKey:@"lng"];
                      
                      
                              coordinates = [NSMutableString stringWithFormat:@"%@,%@",latstring,lngstring];
                      
                      
                      
                      
                                  }
                      
                              }
                      
                              dispatch_sync(dispatch_get_main_queue(), ^
                                            {
                      
                      
                      
                                               // call the required method here..
                      
                                            });
                      
                      
                      
                      
                          }];
                          [datatask resume];   //dont forget it
                      
                          }
                      

                      【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-08-11
                      • 1970-01-01
                      • 2012-04-29
                      • 2019-01-08
                      相关资源
                      最近更新 更多