Objective中更好的JSON解析实现
我正在接收JSON响应,以便在核心数据中保存用户首选项。
preferences={
      1={
        children=({
          3=Samsung;4=Nokia;
        });id=1;name=Mobiles;
      };2={
        children=({
          5="Samsung Curve TV";
        });id=2;name=Electronics;
      };
    };
这是我的代码片段,它工作正常。 但我认为这是非常冗长的代码。
    NSLog(@"Preferences: %@", [response objectForKey:@"preferences"]);
    for (NSDictionary *dic in [response objectForKey:@"preferences"]) {
        NSLog(@"ID: %@", [[[response objectForKey:@"preferences"] objectForKey:dic] objectForKey:@"id"]);
        NSLog(@"NAME: %@", [[[response objectForKey:@"preferences"] objectForKey:dic] objectForKey:@"name"]);
        NSLog(@"Children DIC: %@", [[[[[response objectForKey:@"preferences"]
                                     objectForKey:dic] objectForKey:@"children"] objectAtIndex:0] objectForKey:@"3"]);
        for (NSDictionary *childDic in [[[[response objectForKey:@"preferences"]
                                          objectForKey:dic] objectForKey:@"children"] objectAtIndex:0]) {
            NSLog(@"Child Name: %@", [[[[[response objectForKey:@"preferences"]
                                        objectForKey:dic] objectForKey:@"children"] objectAtIndex:0] objectForKey:childDic]);
        }
    }
我有3个问题。
我该如何改进我的代码片段? 有没有更简单的方法来实现这一点?
这个JSON响应是否足够用于移动端解析? 它是不错的JSON格式? 在使用核心数据方面,是否有任何JSON响应格式作为移动开发人员应遵循(它们只是将数据库实现作为最佳实践减少)?
我如何从Objective-c中再次构造这样的JSON字符串?
  好吧,(对不起,没有深入的分析)首先我要修改你的JSON不要包含动态元素的dictionary (samsung有关键3等等,它应该是数组,有道理?) 
我拿出更好的JSON结构:
{  
   "preferences":[
      {
         "items":[
            {
            "id" : "3",
            "name" : "Samsung" 
            },
            {
            "id" : "3",
            "name" : "Nokia" 
            }
         ],
         "id":"1",
         "name":"Mobiles"
      },
      {  
         "items":[
           {
            "id" : "3",
            "name" : "Nokia" 
            }
         ],
         "id":"2",
         "name":"Electronics"
      }
]
}
  现在使用JSONModel将其映射到对象是非常容易的,只有一件您应该关心的是映射键。 
 NSString *JSONString = @"    {        "preferences":[        {            "items":[            {                "id" : "3",                "name" : "Samsung"            },            {                "id" : "3",                "name" : "Nokia"            }            ],            "id":"1",            "name":"Mobiles"        },        {            "items":[            {                "id" : "3",                "name" : "Nokia"            }            ],            "id":"2",            "name":"Electronics"        }        ]    }";
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:[JSONString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
    NSError *mapError;
    GlobalPreferences *globalPreferences = [[GlobalPreferences alloc] initWithDictionary:dictionary error:&mapError];
    if (mapError) {
        NSLog(@"Something went wrong with mapping model %@", mapError);
    }
    NSLog(@"Your mapped model: %@", globalPreferences);
楷模:
Kinda GlobalPreference,根模型,以防万一你决定添加额外的东西
 #import <JSONModel/JSONModel.h>
    #import "Preference.h"
    @interface GlobalPreferences : JSONModel
    @property (nonatomic, strong) NSArray<Preference> *preferences; // using protocol here you specifying to which model data should be mapped
    @property (nonatomic, strong) NSArray<Optional> *somethingElse; // some other settings may be here
    @end
    #import "GlobalPreferences.h"
    @implementation GlobalPreferences
    @end
偏爱
#import <JSONModel/JSONModel.h>
  #import "PreferenceItem.h"
    @protocol Preference <NSObject>
    @end
    @interface Preference : JSONModel
    @property (nonatomic, strong) NSNumber *ID; // required
    @property (nonatomic, strong) NSString *name; // required
    @property (nonatomic, strong) NSArray<PreferenceItem> *items;
    @end
    #import "Preference.h"
    @implementation Preference
    #pragma mark - JSONModel
    + (JSONKeyMapper *)keyMapper {
        return [[JSONKeyMapper alloc] initWithDictionary:@{
                                                           @"id": @"ID",
                                                           }];
    }
    @end
PreferenceItem
    #import <JSONModel/JSONModel.h>
    // This protocol just to let JSONModel know to which model needs to be parsed data in case if it's an array/dictionary
    @protocol PreferenceItem <NSObject>
    @end
@interface PreferenceItem : JSONModel
@property (nonatomic, strong) NSNumber *ID;
@property (nonatomic, strong) NSString *name;
@end
#import "PreferenceItem.h"
@implementation PreferenceItem
#pragma mark - JSONModel
+ (JSONKeyMapper *)keyMapper {
    return [[JSONKeyMapper alloc] initWithDictionary:@{
                                                       @"id": @"ID",
                                                       }];
}
@end
  对于coreData应该coreData 。 
  也许对于你来说,所有这些都不是必须的,但是当你解析/映射网络响应(比如data types , missing keys , error handling等等)时,你需要关心很多事情。  如果你手动映射 - 你有可能在某天破坏应用程序。 
我知道你问了Objective-C的最佳实践,但我建议切换到Swift并使用SwiftyJSON。 使用Swift,代码比Objective-C更可读。
let prefs = json["preferences"]
let userName = prefs["id"].stringValue
let name = prefs["name"].stringValue
let child = prefs["children"].arrayValue[0].arrayValue[3]
https://github.com/SwiftyJSON/SwiftyJSON
您可以轻松构建自己的JSON结构并使用Alamofire发送它们:
let parameters: [String : AnyObject] = [
  "preferences": [
    "id": "123",
    "name": "John",
    "children": [
       ["3": "Three"]
    ]
  ]
]
let urlReq = NSMutableURLRequest(url)
urlReq.HTTPMethod = .POST
let req = Alamofire.ParameterEncoding.JSON.encode(urlReq, parameters: parameters).0
let request = Alamofire.request(req)
https://github.com/Alamofire/Alamofire
链接地址: http://www.djcxy.com/p/48075.html上一篇: Better JSON parsing implementation in Objective
下一篇: Using Custom Headers for Response Messages; Bad Practice?
