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?