JSON与MODEL互转

2023-11-09

//
//  HYBJSONModel.h
//  Json2ModelDemo
//
//  Created by huangyibiao on 14-9-15.
//  Copyright (c) 2014年 Home. All rights reserved.
//

#import <Foundation/Foundation.h>

/*!
 * @brief JSON转换成Model,或者把Model转换成JSON
 * @author huangyibiao
 */
@interface HYBJSONModel : NSObject

/*!
 * @brief 把对象(Model)转换成字典
 * @param model 模型对象
 * @return 返回字典
 */
+ (NSDictionary *)dictionaryWithModel:(id)model;

/*!
 * @brief 获取Model的所有属性名称
 * @param model 模型对象
 * @return 返回模型中的所有属性值
 */
+ (NSArray *)propertiesInModel:(id)model;

/*!
 * @brief 把字典转换成模型,模型类名为className
 * @param dict 字典对象
 * @param className 类名
 * @return 返回数据模型对象
 */
+ (id)modelWithDict:(NSDictionary *)dict className:(NSString *)className;

@end


//
//  HYBJSONModel.m
//  Json2ModelDemo
//
//  Created by huangyibiao on 14-9-15.
//  Copyright (c) 2014年 Home. All rights reserved.
//

#import "HYBJSONModel.h"
#import <objc/runtime.h>

typedef NS_ENUM(NSInteger, HYBJSONModelDataType) {
    kHYBJSONModelDataTypeObject    = 0,
    kHYBJSONModelDataTypeBOOL      = 1,
    kHYBJSONModelDataTypeInteger   = 2,
    kHYBJSONModelDataTypeFloat     = 3,
    kHYBJSONModelDataTypeDouble    = 4,
    kHYBJSONModelDataTypeLong      = 5,
};

@implementation HYBJSONModel

/*!
 * @brief 把对象(Model)转换成字典
 * @param model 模型对象
 * @return 返回字典
 */
+ (NSDictionary *)dictionaryWithModel:(id)model {
    if (model == nil) {
        return nil;
    }
    
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    
    // 获取类名/根据类名获取类对象
    NSString *className = NSStringFromClass([model class]);
    id classObject = objc_getClass([className UTF8String]);
    
    // 获取所有属性
    unsigned int count = 0;
    objc_property_t *properties = class_copyPropertyList(classObject, &count);
    
    // 遍历所有属性
    for (int i = 0; i < count; i++) {
        // 取得属性
        objc_property_t property = properties[i];
        // 取得属性名
        NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property)
                                                          encoding:NSUTF8StringEncoding];
        // 取得属性值
        id propertyValue = nil;
        id valueObject = [model valueForKey:propertyName];
        
        if ([valueObject isKindOfClass:[NSDictionary class]]) {
            propertyValue = [NSDictionary dictionaryWithDictionary:valueObject];
        } else if ([valueObject isKindOfClass:[NSArray class]]) {
            propertyValue = [NSArray arrayWithArray:valueObject];
        } else {
            propertyValue = [NSString stringWithFormat:@"%@", [model valueForKey:propertyName]];
        }
        
        [dict setObject:propertyValue forKey:propertyName];
    }
    return [dict copy];
}

/*!
 * @brief 获取Model的所有属性名称
 * @param model 模型对象
 * @return 返回模型中的所有属性值
 */
+ (NSArray *)propertiesInModel:(id)model {
    if (model == nil) {
        return nil;
    }
    
    NSMutableArray *propertiesArray = [[NSMutableArray alloc] init];
    
    NSString *className = NSStringFromClass([model class]);
    id classObject = objc_getClass([className UTF8String]);
    unsigned int count = 0;
    objc_property_t *properties = class_copyPropertyList(classObject, &count);
    
    for (int i = 0; i < count; i++) {
        // 取得属性名
        objc_property_t property = properties[i];
        NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property)
                                                          encoding:NSUTF8StringEncoding];
        [propertiesArray addObject:propertyName];
    }
    
    return [propertiesArray copy];
}

/*!
 * @brief 把字典转换成模型,模型类名为className
 * @param dict 字典对象
 * @param className 类名
 * @return 返回数据模型对象
 */
+ (id)modelWithDict:(NSDictionary *)dict className:(NSString *)className {
    if (dict == nil || className == nil || className.length == 0) {
        return nil;
    }
    
    id model = [[NSClassFromString(className) alloc]init];
    
    // 取得类对象
    id classObject = objc_getClass([className UTF8String]);
    
    unsigned int count = 0;
    objc_property_t *properties = class_copyPropertyList(classObject, &count);
    Ivar *ivars = class_copyIvarList(classObject, nil);

    for (int i = 0; i < count; i ++) {
        // 取得成员名
        NSString *memberName = [NSString stringWithUTF8String:ivar_getName(ivars[i])];
        const char *type = ivar_getTypeEncoding(ivars[i]);
        NSString *dataType =  [NSString stringWithCString:type encoding:NSUTF8StringEncoding];
        
        NSLog(@"Data %@ type: %@",memberName,dataType);
        
        HYBJSONModelDataType rtype = kHYBJSONModelDataTypeObject;
        if ([dataType hasPrefix:@"c"]) {
            rtype = kHYBJSONModelDataTypeBOOL;// BOOL
        } else if ([dataType hasPrefix:@"i"]) {
            rtype = kHYBJSONModelDataTypeInteger;// int
        } else if ([dataType hasPrefix:@"f"]) {
            rtype = kHYBJSONModelDataTypeFloat;// float
        } else if ([dataType hasPrefix:@"d"]) {
            rtype = kHYBJSONModelDataTypeDouble; // double
        } else if ([dataType hasPrefix:@"l"])  {
            rtype = kHYBJSONModelDataTypeLong;// long
        }
        
        for (int j = 0; j < count; j++) {
            objc_property_t property = properties[j];
            NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property)
                                                              encoding:NSUTF8StringEncoding];
            NSRange range = [memberName rangeOfString:propertyName];
            
            if (range.location == NSNotFound) {
                continue;
            } else {
                id propertyValue = [dict objectForKey:propertyName];
                
                switch (rtype) {
                    case kHYBJSONModelDataTypeBOOL: {
                        BOOL temp = [[NSString stringWithFormat:@"%@", propertyValue] boolValue];
                        propertyValue = [NSNumber numberWithBool:temp];
                    }
                        break;
                    case kHYBJSONModelDataTypeInteger: {
                        int temp = [[NSString stringWithFormat:@"%@", propertyValue] intValue];
                        propertyValue = [NSNumber numberWithInt:temp];
                    }
                        break;
                    case kHYBJSONModelDataTypeFloat: {
                        float temp = [[NSString stringWithFormat:@"%@", propertyValue] floatValue];
                        propertyValue = [NSNumber numberWithFloat:temp];
                    }
                        break;
                    case kHYBJSONModelDataTypeDouble: {
                        double temp = [[NSString stringWithFormat:@"%@", propertyValue] doubleValue];
                        propertyValue = [NSNumber numberWithDouble:temp];
                    }
                        break;
                    case kHYBJSONModelDataTypeLong: {
                        long long temp = [[NSString stringWithFormat:@"%@",propertyValue] longLongValue];
                        propertyValue = [NSNumber numberWithLongLong:temp];
                    }
                        break;
                        
                    default:
                        break;
                }
                
                [model setValue:propertyValue forKey:memberName];
                break;
            }
        }
    }
    return model;
}

@end


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JSON与MODEL互转 的相关文章

  • sql_model处理方案

    1 查询sql model的值 select sql mode 2 先贴一个大多数数据库的配置 STRICT TRANS TABLES NO ZERO IN DATE NO ZERO DATE ERROR FOR DIVISION BY Z
  • 算法题:(二分搜索)

    class Solution public int binarySearch vector
  • vue.js -- 动态组件&异步组件

    目录 动态组件 点击切换组件 优化点击切换组件 使用component标签优化代码 使用keep alive标签完善功能 异步组件 总结 动态组件 根据数据的变化 动态切换组件的显示 点击切换组件 首先定义两个子组件 子组件 app com
  • 读《游戏之旅--我的编程感悟》有感

    我不是学计算机的 但此书给我的感触颇深 此书成于2005年 我真希望自己能早6年读到这本书呀 2007年大学的时候就读到 作者叫云风 个人主页 www codingnow com 是个技术高手 网易游戏开发部门的重要人物 他书中有这样一段话
  • 【RabbitMQ教程】Work queues 工作队列模式

    目录 前言 Work queues工作模式介绍 消息模型 适用场景 消费策略 重要 消费策略选择 消费策略代码示例 轮询分发 1 定义生产者和消费者 2 运行程序 3 结果分析 公平分发 1 定义生产者和消费者 2 运行程序 3 结果分析
  • 憨批的语义分割3——unet模型详解以及训练自己的unet模型(划分斑马线)

    憨批的语义分割3 unet模型详解以及训练自己的unet模型 划分斑马线 学习前言 模型部分 什么是unet模型 unet模型的代码实现 1 主干模型Mobilenet 2 unet的Decoder解码部分 代码测试 训练部分 训练的是什么
  • 蓝桥杯-第六届蓝桥杯C语言A组/B组/C组-Python题解

    目录 方程整数解 星系炸弹 奇妙的数字 牌型种数 手链样式 饮料换购 奖券数目 三羊献瑞 加法变乘法 隔行变色 立方尾不变 方程整数解 方程 a 2 b 2 c 2 1000 这个方程有整数解吗 有 a b c 6 8 30 就是一组解 你
  • 猫眼美团滑块

    猫眼演场会下单会弹出美团的滑块验证码 使用js过滑块 想看演唱会但是又抢不到票 用python写一个猫眼自动下单
  • 2020年最常见的25个Web开发面试问题

    Java面试笔试面经 Java技术每天学习一点 Java面试 关注不迷路 作者 Team Codegiant 译者 王强 策划 李俊辰 本文最初发布于 Medium 网站 经原作者授权由 InfoQ 中文站翻译并分享 你把闹钟设定在了下午
  • 软件测试值不值得学,2023软件测试行情分析

    目录 1 人们的生活离不开软件 有软件的地方就有测试 2 测试工程师特别是自动化测试工程师的需求会越来越大 3 软件测试经验越丰富越受欢迎 不存在35岁限制 4 所有新兴行业比如chat gtp 车载系统等都需要测试工程师 薪资 就业 软件
  • Office2010安装步骤

    这是一篇我自己写于17年8月27日的office2010的安装教程 发现挺多人都不会安装或者激活 所以特地写了这篇文 安装office2010前请确保电脑中没有安装其它版本的office软件 否则可能造成两个版本的office不能正常使用
  • MATLAB:矩阵(基础知识)

    一 数组的创建和操作 1 矩阵的输入 gt gt A A gt gt B 6 5 3 B 6 5 3 gt gt C B C 6 5 3 2 调用矩阵 gt gt A 1 2 3 4 5 A 1 2 3 4 5 gt gt a1 A 1 访
  • kvm设置桥接网卡

    kvm默认的网卡模式为nat 虚拟主机可访问外网 但外部无法访问虚拟主机 将其改为桥接模式以实现内外互通 环境 centos6图形界面下 有virtual machine manager 程序 整个过程就两步 1 修改物理机网卡为桥接模式
  • SpringBoot报错:Cannot call isReadOnlyBeforeAttachedToSession when isReadOnlySettingAvailable == true

    错误后边会说明哪个实体类导致的 在实体类上加上 Proxy lazy false
  • Apache Beam实战指南

    https mp weixin qq com s biz MzU1NDA4NjU2MA mid 2247492538 idx 2 sn 9a2bd9fe2d7fd681c10ebd368ef81c9c chksm fbea5a75cc9dd
  • [原创]LoadRunner 12.02 录制脚本时提示无Internet访问,如何解决?

    在使用LoadRunner 12 02 进行录制脚本时提示无Internet访问 如下图 翻译中文如下 可以尝试以下方式解决 点击弹出框中的 Yes 即可 若还是有问题 尝试以下方式 1 LR12走的是证书机制 你按照我附件 图片1 中提供
  • springboot集成springsecurity + jwt的使用

    当项目中要用到用户的认证及权限的时候我们一般会使用 springSecurity来解决 引入 引入很简单

随机推荐

  • 学习若依框架----之----获取登录登录系统、ip、浏览器信息

    文章目录 1 导入需要用到的依赖 2 IP获取 3 AddressUtils 获取地址类 4 登录日志管理工具 4 SpringUtils获取bean工具 5 客户端工具 6 使用 7 测试 8 数据库记录 若依里面 创建登录日志是根据异步
  • USDT信用卡和转账入账接口

    class Usdtpay public function index data this gt request gt param uid data uid token data token type data type changeid
  • 经验模态分解(EMD)

    目录 1 背景 2 时间序列平稳性 3 EMD 方法 4 EMD 过程 5 EMD 方法的缺陷 6 Python 1 背景 实际工程测量中由于测量系统受外界环境影响经常在测量信号中产生趋势项 趋势项是指信号中周期大于采样长度的频率成分 通常
  • Unity内存与资源管理

    内存管理是程序开发的核心问题 而资源的使用又与内存息息相关 因此本章想要梳理整个开发流程中Unity对于内存与资源的管理方式 一 内存基础 1 1 基础概念 内存是暂时存放CPU中的运算数据 与硬盘等外部存储器交换的数据 在操作系统中 内存
  • R语言产生随机数

    R语言中有4个产生随机数的函数 dunif 指定随机数密度 punif 指定随机数的分布类型 qunif 指定quantile function runif 产生随机分布的散点 如果需要指定随机数的类型 可用以下几个函数 round 四舍五
  • kubernetes deploy standalone mysql demo

    文章目录 deployment mysql standalone statefulset mysql standalone helm install mysql standalone deployment mysql standalone
  • mac连接linux报错Unable to negotiate with port 22: no matching host key type found. Their offer: ssh-rsa,

    mac 使用ssh连接linux服务器报错 Unable to negotiate with 10 254 8 211 port 22 no matching host key type found Their offer ssh rsa
  • 软件测试怎么去介绍一个项目的测试流程?

    1 自我介绍 以XXX简历来举例 参照下面的案例 编写你的自我介绍 框架就是 我是谁 我做过什么 我能做什么 我来的目的是什么 面试官您好 我叫 毕业之后进入河北东软软件有限公司从事软件测试方面的工作 一开始从底层做起 在工作中逐渐接触和学
  • shell脚本启动jar包示例

    这里主要为shell脚本启动部署在服务器中jar包 bin bash 这里可替换为你自己的执行程序 其他代码无需更改 APP NAME demo jar 使用说明 用来提示输入参数 usage echo Usage sh demo sh s
  • 数据结构和算法(1)-----稀疏数组

    一 实际需求 编写的五子棋程序中 有存盘退出和继续上盘的功能 分析问题 因为该二维数组的很多值是默认值0 因此记录了很多没有意思的数据 如何在计算机中高效的存储这样的二维数组是一个需要考虑的问题 二 基本介绍 当一个数组中大部分元素为0 或
  • CTF.show:web6

    登陆窗 先想到sql注入 抓包测试发现失败 利用 代替空格进行绕过 username admin or 1 1 password 123456 利用联合查询找到回显位置 username admin or 1 1 union select
  • IDispose

    需要为本类提供DISPOSE函数的情况 1 从IDispose继承 2 有成员对象实现了IDispose 3 本类有包装本机资源 需要在回收对象堆内存前进行释放 Dispose函数并不会将托管对象从托管堆删除 只会回收内部的本机资源
  • 万向锁的理解

    万向锁 万向锁这个概念其实还是不大好理解的 看了很多的博客 虽然看起来他们讲的很有道理 可还是想不通 希望我这篇文章能讲清楚 万向锁产生的根本原因是绕三个轴的旋转不是同时进行的 想象一下我们旋转矩阵的推导是不是绕三个轴的旋转矩阵乘起来得到的
  • 测试用例设计白皮书--测试用例设计综合策略

    测试用例设计白皮书 测试用例设计综合策略 Author Vince 来源 http blog csdn net vincetest 1 Myers提出了使用各种测试方法的综合策略 1 在任何情况下都必须使用边界值分析方法 经验表明用这种方法
  • 微信小程序-SOA架构(17年1月)

    微信小程序 顾名思义 它有两个方面的含义 重点在小 也就是不用安装就能使用的意思 另一个重点 它是应用程序 它和公众号绑定在一起使用 从用户角度去看 它是各种APP的替代品 有了它以后 不再需要安装APP 作为IT人员 更多的是从工程思维的
  • Snort搭建以及规则编写

    目录 Snort IDS Snort搭建 安装web服务 方便设置sonrt后期访问 Mysql安装 PHP安装 安装 Snort Snort配置 创建snort专用的用户和组 配置目录 配置规则 修改配置文件 规则编写 Snort IDS
  • QGIS二次开发02:交互动作实现

    地图交互动作就是通过鼠标操作与地图间的互动 动作包括按下 press 按键弹起 release 鼠标移动 move 双击等等 QGIS实现地图的交互主要是通过继承QgsMapTool这个类实现 目前集成了QgsMapToolZoom 拉框缩
  • 数据结构---堆的构建和堆排序(向下、向上调整算法)

    一 建堆 1 堆的概念及性质 如果有一个关键码的集合 K k0 k1 k2 kn 1 把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中 并满足 Ki lt K2 i 1 且 Ki lt K2 i 2 Ki gt K2 i 1 且
  • 七大排序知识点

    目录 1 稳定性 2 冒泡排序 3 插入排序 3 1 折半插入排序 4 希尔排序 5 选择排序 6 堆排序 7 快速排序 挖坑法 8 归并排序 9 海量数据的排序问题 1 稳定性 两个相等的数据 如果经过排序后 排序算法能保证其相对位置不发
  • JSON与MODEL互转

    HYBJSONModel h Json2ModelDemo Created by huangyibiao on 14 9 15 Copyright c 2014年 Home All rights reserved import