IOS 字典模型互转框架 MJExtension

时间:2021-07-18 01:08:13
IOS 字典模型互转框架 MJExtension
 

能做什么?

  • MJExtension是一套字典和模型之间互相转换的超轻量级框架

  • MJExtension能完成的功能

    • 字典(JSON) --> 模型(Model)

    • 模型(Model) --> 字典(JSON)

    • 字典数组(JSON Array) --> 模型数组(Model Array)

    • 模型数组(Model Array) --> 字典数组(JSON Array)

  • 详尽用法主要参考 main.m中的各个函数 以及 NSObject+MJKeyValue.h

MJExtension和JSONModel、Mantle等框架的区别

  • 转换速率:

    • 最近一次测试表明:MJExtension > JSONModel > Mantle

    • 各位开发者也可以自行测试

  • 具体用法:

    • JSONModel:要求所有模型类必须继承自JSONModel基类

    • Mantle:要求所有模型类必须继承自MTModel基类

    • MJExtension不需要你的模型类继承任何特殊基类,毫无污染,毫无侵入性

如何使用MJExtension

  • cocoapods导入:pod 'MJExtension'

  • 手动导入:

    • MJExtensionExample/MJExtensionExample/MJExtension文件夹中的所有源代码拽入项目中

    • 导入主头文件:#import "MJExtension.h"

MJExtension.h
MJConst.h               MJConst.m
MJFoundation.h          MJFoundation.m
MJIvar.h                MJIvar.m
MJType.h                MJType.m
NSObject+MJCoding.h     NSObject+MJCoding.m
NSObject+MJIvar.h       NSObject+MJIvar.m
NSObject+MJKeyValue.h   NSObject+MJKeyValue.m

最简单的字典转模型

typedef enum {
    SexMale,
    SexFemale
} Sex; @interface User : NSObject
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *icon;
@property (assign, nonatomic) int age;
@property (assign, nonatomic) double height;
@property (strong, nonatomic) NSNumber *money;
@property (assign, nonatomic) Sex sex;
@end NSDictionary *dict = @{
               @"name" : @"Jack",
               @"icon" : @"lufy.png",
               @"age" : @20,
               @"height" : @"1.55",
               @"money" : @100.9,
               @"sex" : @(SexFemale)
            }; // 将字典转为User模型
User *user = [User objectWithKeyValues:dict]; NSLog(@"name=%@, icon=%@, age=%d, height=%@, money=%@, sex=%d", 
    user.name, user.icon, user.age, user.height, user.money, user.sex);
// name=Jack, icon=lufy.png, age=20, height=1.550000, money=100.9, sex=1
核心代码
  • [User objectWithKeyValues:dict]

模型中嵌套模型

@interface Status : NSObject
/** 微博文本内容 */
@property (copy, nonatomic) NSString *text;
/** 微博作者 */
@property (strong, nonatomic) User *user;
/** 转发的微博 */
@property (strong, nonatomic) Status *retweetedStatus;
@end NSDictionary *dict = @{
               @"text" : @"是啊,今天天气确实不错!",
               @"user" : @{
                   @"name" : @"Jack",
                   @"icon" : @"lufy.png"
                },
               @"retweetedStatus" : @{
                   @"text" : @"今天天气真不错!",
                   @"user" : @{
                       @"name" : @"Rose",
                       @"icon" : @"nami.png"
                    }
                }
            }; // 将字典转为Status模型
Status *status = [Status objectWithKeyValues:dict]; NSString *text = status.text;
NSString *name = status.user.name;
NSString *icon = status.user.icon;
NSLog(@"text=%@, name=%@, icon=%@", text, name, icon);
// text=是啊,今天天气确实不错!, name=Jack, icon=lufy.png NSString *text2 = status.retweetedStatus.text;
NSString *name2 = status.retweetedStatus.user.name;
NSString *icon2 = status.retweetedStatus.user.icon;
NSLog(@"text2=%@, name2=%@, icon2=%@", text2, name2, icon2);
// text2=今天天气真不错!, name2=Rose, icon2=nami.png
核心代码
  • [Status objectWithKeyValues:dict]

模型中有个数组属性,数组里面又要装着其他模型

@interface Ad : NSObject
@property (copy, nonatomic) NSString *image;
@property (copy, nonatomic) NSString *url;
@end @interface StatusResult : NSObject
/** 存放着一堆的微博数据(里面都是Status模型) */
@property (strong, nonatomic) NSMutableArray *statuses;
/** 存放着一堆的广告数据(里面都是Ad模型) */
@property (strong, nonatomic) NSArray *ads;
@property (strong, nonatomic) NSNumber *totalNumber;
@end @implementation StatusResult
// 实现这个方法的目的:告诉MJExtension框架statuses和ads数组里面装的是什么模型
/*
+ (NSDictionary *)objectClassInArray
{
    return @{
         @"statuses" : [Status class],
         @"ads" : [Ad class]
    };
}
+ (Class)objectClassInArray:(NSString *)propertyName
{
    if ([propertyName isEqualToString:@"statuses"]) {
        return [Status class];
    } else if ([propertyName isEqualToString:@"ads"]) {
        return [Ad class];
    }
    return nil;
}
*/
// 这个方法对比上面的2个方法更加没有侵入性和污染,因为不需要导入Status和Ad的头文件
+ (NSDictionary *)objectClassInArray
{
    return @{
         @"statuses" : @"Status",
         @"ads" : @"Ad"
    };
}
@end NSDictionary *dict = @{
                       @"statuses" : @[
                           @{
                               @"text" : @"今天天气真不错!",
                               @"user" : @{
                                   @"name" : @"Rose",
                                   @"icon" : @"nami.png"
                               }
                            },
                           @{
                               @"text" : @"明天去旅游了",
                               @"user" : @{
                                   @"name" : @"Jack",
                                   @"icon" : @"lufy.png"
                               }
                            }
                        ],
                       @"ads" : @[
                           @{
                               @"image" : @"ad01.png",
                               @"url" : @"http://www.ad01.com"
                           },
                           @{
                               @"image" : @"ad02.png",
                               @"url" : @"http://www.ad02.com"
                           }
                       ],
                       @"totalNumber" : @"2014"
                    }; // 将字典转为StatusResult模型
StatusResult *result = [StatusResult objectWithKeyValues:dict]; NSLog(@"totalNumber=%@", result.totalNumber);
// totalNumber=2014 // 打印statuses数组中的模型属性
for (Status *status in result.statuses) {
    NSString *text = status.text;
    NSString *name = status.user.name;
    NSString *icon = status.user.icon;
    NSLog(@"text=%@, name=%@, icon=%@", text, name, icon);
}
// text=今天天气真不错!, name=Rose, icon=nami.png
// text=明天去旅游了, name=Jack, icon=lufy.png // 打印ads数组中的模型属性
for (Ad *ad in result.ads) {
    NSLog(@"image=%@, url=%@", ad.image, ad.url);
}
// image=ad01.png, url=http://www.ad01.com
// image=ad02.png, url=http://www.ad02.com
核心代码
  • 在模型内部实现+ (NSDictionary *)objectClassInArray方法

  • [StatusResult objectWithKeyValues:dict]

模型中的属性名和字典中的key不相同(或者需要多级映射)

@interface Bag : NSObject
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) double price;
@end @interface Student : NSObject
@property (copy, nonatomic) NSString *ID;
@property (copy, nonatomic) NSString *desc;
@property (copy, nonatomic) NSString *nowName;
@property (copy, nonatomic) NSString *oldName;
@property (copy, nonatomic) NSString *nameChangedTime;
@property (strong, nonatomic) Bag *bag;
@end @implementation Student
// 实现这个方法的目的:告诉MJExtension框架模型中的属性名对应着字典的哪个key
+ (NSDictionary *)replacedKeyFromPropertyName
{
    return @{
                @"ID" : @"id",
                @"desc" : @"desciption",
                @"oldName" : @"name.oldName",
                @"nowName" : @"name.newName",
                @"nameChangedTime" : @"name.info.nameChangedTime",
                @"bag" : @"other.bag"
            };
}
@end NSDictionary *dict = @{
                       @"id" : @"20",
                       @"desciption" : @"孩子",
                       @"name" : @{
                            @"newName" : @"lufy",
                            @"oldName" : @"kitty",
                            @"info" : @{
                                @"nameChangedTime" : @"2013-08"
                            }
                       },
                       @"other" : @{
                            @"bag" : @{
                                @"name" : @"小书包",
                                @"price" : @100.7
                            }
                       }
                   }; // 将字典转为Student模型
Student *stu = [Student objectWithKeyValues:dict]; // 打印Student模型的属性
NSLog(@"ID=%@, desc=%@, oldName=%@, nowName=%@, nameChangedTime=%@",
          stu.ID, stu.desc, stu.oldName, stu.nowName, stu.nameChangedTime);
// ID=20, desc=孩子, oldName=kitty, nowName=lufy, nameChangedTime=2013-08
NSLog(@"bagName=%@, bagPrice=%f", stu.bag.name, stu.bag.price);
// bagName=小书包, bagPrice=100.700000
核心代码
  • 在模型内部实现+ (NSDictionary *)replacedKeyFromPropertyName方法

  • [Student objectWithKeyValues:dict]

将一个字典数组转成模型数组

NSArray *dictArray = @[
                       @{
                           @"name" : @"Jack",
                           @"icon" : @"lufy.png",
                        },
                       @{
                           @"name" : @"Rose",
                           @"icon" : @"nami.png",
                        }
                    ]; // 将字典数组转为User模型数组
NSArray *userArray = [User objectArrayWithKeyValuesArray:dictArray]; // 打印userArray数组中的User模型属性
for (User *user in userArray) {
    NSLog(@"name=%@, icon=%@", user.name, user.icon);
}
// name=Jack, icon=lufy.png
// name=Rose, icon=nami.png
核心代码
  • [User objectArrayWithKeyValuesArray:dictArray]

将一个模型转成字典

// 新建模型
User *user = [[User alloc] init];
user.name = @"Jack";
user.icon = @"lufy.png"; Status *status = [[Status alloc] init];
status.user = user;
status.text = @"今天的心情不错!"; // 将模型转为字典
NSDictionary *statusDict = status.keyValues;
NSLog(@"%@", statusDict);
/*
{
    text = "今天的心情不错!";
    user =     {
        icon = "lufy.png";
        name = Jack;
    };
}
*/ // 多级映射的模型
Student *stu = [[Student alloc] init];
stu.ID = @"123";
stu.oldName = @"rose";
stu.nowName = @"jack";
stu.desc = @"handsome";
stu.nameChangedTime = @"2018-09-08"; Bag *bag = [[Bag alloc] init];
bag.name = @"小书包";
bag.price = 205;
stu.bag = bag; NSDictionary *stuDict = stu.keyValues;
NSLog(@"%@", stuDict);
/*
{
    desciption = handsome;
    id = 123;
    name =     {
        info =         {
            nameChangedTime = "2018-09-08";
        };
        newName = jack;
        oldName = rose;
    };
    other =     {
        bag =         {
            name = "小书包";
            price = 205;
        };
    };
}
*/
核心代码
  • status.keyValuesstu.keyValues

将一个模型数组转成字典数组

// 新建模型数组
User *user1 = [[User alloc] init];
user1.name = @"Jack";
user1.icon = @"lufy.png"; User *user2 = [[User alloc] init];
user2.name = @"Rose";
user2.icon = @"nami.png"; NSArray *userArray = @[user1, user2]; // 将模型数组转为字典数组
NSArray *dictArray = [User keyValuesArrayWithObjectArray:userArray];
NSLog(@"%@", dictArray);
/*
(
    {
        icon = "lufy.png";
        name = Jack;
    },
    {
        icon = "nami.png";
        name = Rose;
    }
)
*/
核心代码
  • [User keyValuesArrayWithObjectArray:userArray]

更多用法

  • 参考NSObject+MJKeyValue.h

  • 参考NSObject+MJCoding.h

IOS 字典模型互转框架 MJExtension的更多相关文章

  1. Swift 字典模型互转总结

    现在很多iOS项目的开发开始转向Swift语言. 相信 Swift语言很快会成为iOS工程师 必备技能. 字典转模型, 模型转转字典在开发过程中扮演非常重要的角色. 今天就和大家分享一下使用Swift ...

  2. 序列化框架MJExtension详解 + iOS ORM框架

    当开发中你的模型中属性名称和 字典(JSON/XML) 中的key 不能一一对应时, 或者当字典中嵌套了多层字典数组时..., 以及教你如何用 MJExtension 配置类来统一管理你的模型配置, ...

  3. iOS第三方Api及常用框架总结

    iOS常用框架汇总: SVProgressHUD:产生覆盖层,禁止某种操作 SDWebImage: 专业下载图片框架 AFN:网络数据请求框架 MJExtension,模型对象之间互转 第三方分享第三 ...

  4. Android &Swift iOS开发:语言与框架对比

    转载自:http://www.infoq.com/cn/articles/from-android-to-swift-ios?utm_campaign=rightbar_v2&utm_sour ...

  5. ios系统架构及常用框架

    1.iOS基于UNIX系统,因此从系统的稳定性上来说它要比其他操作系统的产品好很多 2.iOS的系统架构分为四层,由上到下一次为:可触摸层(Cocoa Touch layer).媒体层(Media l ...

  6. iOS 字典或者数组和JSON串的转换

    在和服务器交互过程中,会iOS 字典或者数组和JSON串的转换,具体互换如下: // 将字典或者数组转化为JSON串 + (NSData *)toJSONData:(id)theData { NSEr ...

  7. iOS 字典与JSON相互转换

    iOS 字典与JSON相互转换 首先简单说一下为什么会写这种幼稚的文章. 现在的网络请求几乎都是AFN完成的,AFN也为我们写了了JSON转换字典的方法,但是不要忘记后台是一个很爱用JSON的人群,H ...

  8. iOS开发之常用第三方框架(下载地址,使用方法,总结)

    iOS开发之常用第三方框架(下载地址,使用方法,总结) 说句实话,自学了这么久iOS,如果说我不知道的但是又基本上都摸遍了iOS相关知识,但是每次做项目的时候,遇到难一点的地方或者没试过的东西就闷了. ...

  9. iOS Swift WisdomHUD 提示界面框架

    iOS Swift WisdomHUD 提示界面框架  Framework Use profile(应用简介) 一:WisdomHUD简介 今天给大家介绍一款iOS的界面显示器:WisdomHUD,W ...

随机推荐

  1. [LeetCode] Super Ugly Number 超级丑陋数

    Write a program to find the nth super ugly number. Super ugly numbers are positive numbers whose all ...

  2. VS 扩展推荐

    Visual Studio 工欲善其事,必先利器.本着这样的观念,对于经常使用的工具,我喜欢去研究研究,帮助我提高效率. Visual Studio Microsoft Visual Studio(简 ...

  3. Oracle字符串分割函数

    今天在创建视图的时候,碰到一个问题,问题如下: 将字符格式为“XXX,YYY”分割出来,并且分割后作为两个字段放入视图中. 考虑使用字符分割函数,但是查找资料Oracle没有字符分割的函数(我对Ora ...

  4. mysql用户和权限管理

    用户和权限管理 Information about account privileges is stored in the user, db, host, tables_priv, columns_p ...

  5. openGl超级宝典学习笔记 (1)第一个三角形

    执行效果 代码及解析: // // Triangle.cpp // Triangle // // Created by fengsser on 15/6/20. // Copyright (c) 20 ...

  6. mysql innodb存储引擎和myisam引擎

    InnoDb存储引擎面向在线事务处理,其特点是行锁设计.支持外键.并支持Oricle似得非锁定读(所谓非锁定读是如果数据库实例读取的行正在进行更新或删除操作当前读取不会等待当前锁的释放而是读取当前行的 ...

  7. TypeScript 模块系统

    https://www.cnblogs.com/niklai/p/5808789.html

  8. IdentityServer4:Endpoint

    Endpoint的概念在IdentityServer里其实就是一些资源操作的url地址:如同Restful API里面的Endpoint是概念: 那么可以通过你自己的授权服务端得到相对应的地址与信息: ...

  9. NSIS+Duilib 制作Windows安装包

    转载:https://www.cnblogs.com/zzllily/articles/5443850.html 转载:https://blog.csdn.net/bruce135lee/articl ...

  10. java.lang.ClassCastException: android.os.BinderProxy cannot be cast to com.test.Test

    由于我在第二个Activity中指定了进程名字,但是服务却没有指定进程名(默认跟主入口一个进程)所以报错. 网上找到的是 服务 和绑定服务的客户端必须在同一个application或者进程中,所以Ma ...