一、系统自带的json转换为字典
系统自带的转化主要使用NSJSONSerialization类来完成;json格式字符串转字典使用JSONObjectWithData:option:error函数来转换;字典转json格式字符串使用dataWithJSONObject:option:error
/*!
* @brief 把格式化的JSON格式的字符串转换成字典
* @param jsonString JSON格式的字符串
* @return 返回字典
*/
json格式字符串转字典:
+ (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString {
if (jsonString == nil) {
return nil;
}
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *err;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];
if(err) {
NSLog(@"json解析失败:%@",err);
return nil;
}
return dic;
}
字典转json格式字符串:
+ (NSString*)dictionaryToJson:(NSDictionary *)dic
{
NSError *parseError = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&parseError];
return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
NSJSONWritingPrettyPrinted 是有换位符的。
如果NSJSONWritingPrettyPrinted 是nil 的话 返回的数据是没有 换位符的
二、关于这个知识点,并没有太多难点,其中主要要记住的就是字典转模型,字典转模型一般步骤如下:
(1)首先创建一个模型类,创建需要数据的 get 和 set 方法,由编译器合成
例如:
@property (nonatomic, copy) NSString *answer;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *icon;
(2)在一个类中(假设为 MJQuestion)创建两个方法(一个类方法、一个对象方法,作用是一样的),传入 一个字典,取出数据用 get 方法保存到成员变量中,例如:
- (instancetype)initWithDict:(NSDictionary *)dict
{
if(self = [super init])
{
//1、KVC版本
//[self setValue:dict[@"icon"] forKeyPath:@"icon"];
//[self setValue:dict[@"answer"] forKeyPath:@"answer"];
//[self setValue:dict[@"options"] forKeyPath:@"options"];
//2、属性
self.icon = dict[@"icon"];
self.answer = dict[@"answer"];
self.options = dict[@"options"];
//3、setValuesForKeysWithDictionary
//[self setValuesForKeysWithDictionary:dict];
}
return self;
}
+ (instancetype)questionWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}
(3)如果将 plist 文件中的数据转成字典,并传给上面方法,返回值为 MJQuestion 对象,再将对象保存到 NSMutableArray 中,之后读取数据时就可以根据 NSMutableArray 索引取出每个 MJQuestion 对象,再从 MJQuestion 对象中读取数据显示到相关控件上。如果是服务器传来的字典,转成模型也类似
部分代码如下:
- (NSArray *)questions
{
if (_questions == nil)
{
// 1.加载 plist
NSArray *dictArray =
[NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"questions" ofType:@"plist"]];
// 2.字典转模型
NSMutableArray *questionArray = [NSMutableArray array];
for (NSDictionary *dict in dictArray)
{
MJQuestion *question = [MJQuestion questionWithDict:dict];
[questionArray addObject:question];
}
// 3.赋值
_questions = questionArray;
}
return _questions;
}
三、runtime给OC动态性的提供强大的支持,下面列举了利用runtime实现字典模型的转换
//字典转模型
-(instancetype)initWithDictionary:(NSDictionary *)dictionary{
self = [super init];
if (self) {
for (NSString *key in dictionary.allKeys) {
id value = dictionary[key];
SEL setter = [self propertySetterByKey:key];
if (setter) {
((void (*)(id, SEL, id))objc_msgSend)(self, setter, value);
}
}
}
return self;
}
//模型转字典
-(NSDictionary *)covertToDictionary{
unsigned int count = 0;
objc_property_t *properties = class_copyPropertyList([self class], &count);
if (count != 0 ) {
NSMutableDictionary *result = [@{} mutableCopy];
for (NSUInteger i = 0; i < count; i ++) {
const void *propertyName = property_getName(properties[i]);
NSString *name = [NSString stringWithUTF8String:propertyName];
SEL getter = [self propertyGetterBykey:name];
if (getter) {
id value = ((id (*)(id, SEL))objc_msgSend)(self, getter);
if(value){
result[name] = value;
}else{
result[name] = @"字典的key对应的value不能为nil哦!";
}
}
}
free(properties);
return result;
}
free(properties);
return nil;
}
#pragma mark - private method
//生成setter方法
-(SEL)propertySetterByKey:(NSString *)key{
//设置方法的setS...大写
NSString *propertySetterName = [NSString stringWithFormat:@"set%@:",key.capitalizedString];
SEL setter = NSSelectorFromString(propertySetterName);
if ([self respondsToSelector:setter]) {
return setter;
}
return nil;
}
//生成getter方法
-(SEL)propertyGetterBykey:(NSString *)key{
SEL getter = NSSelectorFromString(key);
if ([self respondsToSelector:getter]) {
return getter;
}
return nil;
}
字典转模型的实现:https://github.com/onebutterflyW/DictionaryConvertModel
runtime的实现:https://github.com/onebutterflyW/runtime