因项目中需要,实现了一个模型转换字典的方法,支持递归处理。方便快速将模型转换为字典或将属性转化为json,与javascript或后台通信的需求。
.h文件:
#import <Foundation/Foundation.h>
@interface NSObject (ModelToDictionary)
/**
* 模型转字典
*
* @return 字典
*/
- (NSDictionary *)dictionaryFromModel;
/**
* 带model的数组或字典转字典
*
* @param object 带model的数组或字典转
*
* @return 字典
*/
- (id)idFromObject:(nonnull id)object;
@end
.m文件:
#import "NSObject+ModelToDictionary.h"
#import <objc/runtime.h>
@implementation NSObject (ModelToDictionary)
- (NSDictionary *)dictionaryFromModel
{
unsigned int count = 0;
objc_property_t *properties = class_copyPropertyList([self class], &count);
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:count];
for (int i = 0; i < count; i++) {
NSString *key = [NSString stringWithUTF8String:property_getName(properties[i])];
id value = [self valueForKey:key];
//only add it to dictionary if it is not nil
if (key && value) {
if ([value isKindOfClass:[NSString class]]
|| [value isKindOfClass:[NSNumber class]]) {
// 普通类型的直接变成字典的值
[dict setObject:value forKey:key];
}
else if ([value isKindOfClass:[NSArray class]]
|| [value isKindOfClass:[NSDictionary class]]) {
// 数组类型或字典类型
[dict setObject:[self idFromObject:value] forKey:key];
}
else {
// 如果model里有其他自定义模型,则递归将其转换为字典
[dict setObject:[value dictionaryFromModel] forKey:key];
}
} else if (key && value == nil) {
// 如果当前对象该值为空,设为nil。在字典中直接加nil会抛异常,需要加NSNull对象
[dict setObject:[NSNull null] forKey:key];
}
}
free(properties);
return dict;
}
- (id)idFromObject:(nonnull id)object
{
if ([object isKindOfClass:[NSArray class]]) {
if (object != nil && [object count] > 0) {
NSMutableArray *array = [NSMutableArray array];
for (id obj in object) {
// 基本类型直接添加
if ([obj isKindOfClass:[NSString class]]
|| [obj isKindOfClass:[NSNumber class]]) {
[array addObject:obj];
}
// 字典或数组需递归处理
else if ([obj isKindOfClass:[NSDictionary class]]
|| [obj isKindOfClass:[NSArray class]]) {
[array addObject:[self idFromObject:obj]];
}
// model转化为字典
else {
[array addObject:[obj dictionaryFromModel]];
}
}
return array;
}
else {
return object ? : [NSNull null];
}
}
else if ([object isKindOfClass:[NSDictionary class]]) {
if (object && [[object allKeys] count] > 0) {
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
for (NSString *key in [object allKeys]) {
// 基本类型直接添加
if ([object[key] isKindOfClass:[NSNumber class]]
|| [object[key] isKindOfClass:[NSString class]]) {
[dic setObject:object[key] forKey:key];
}
// 字典或数组需递归处理
else if ([object[key] isKindOfClass:[NSArray class]]
|| [object[key] isKindOfClass:[NSDictionary class]]) {
[dic setObject:[self idFromObject:object[key]] forKey:key];
}
// model转化为字典
else {
[dic setObject:[object[key] dictionaryFromModel] forKey:key];
}
}
return dic;
}
else {
return object ? : [NSNull null];
}
}
return [NSNull null];
}
@end
调用:
[someModel dictionaryFromModel];