为什么唱吧iOS 6.0选择了Mantle

iOS ——Mantle Mantle--国外程序员最常用的iOS模型&字典转换框架,Mantle可以轻松把JSON数据、字典(Dictionary)和模型(即Objective对象)之间的相互转换,支持自定义映射,并且内置实现了NSCoding和NSCoping,大大简化归档操作。 立即下载

最近唱吧iOS的6.0版本已经成功上线了。18人月的投入,2500个commit,几十万行的代码修改。唱吧iOS已经从内至外焕然一新,感谢一起并肩作战的小伙伴们。

6.0一个很重大的修改就是基于Mantle重建(新建)了Model层。这里不对Mantle作更多介绍,只分享一下使用Mantle的决策及执行过程。

我们遇到的问题

唱吧是一款上线2年多的App,产品形态的演进和迭代非常快。因此不可避免的遗留了各种问题:

  • Model层不健全,没有统一的结构,不同工程师做法差异很大;多数是哑类型,且没有统一的序列化机制
  • 业务逻辑冗余、分散、不一致
  • 模块划分随意,依赖关系混乱,维护困难
  • NSDictionary作为承载业务的数据类型在各处出现(sqlite, Model object, API, Notification, web, OpenURL etc.),参数和值的正确性完全没有编译器检查,字符串很容易写错,风险延后至运行时,易产生低级bug
  • 基本没有文档和注释(结合上一点,不挂debugger很难读懂代码)
  • 几百个API,业务复杂,变动快,重构难;同一个API请求可能有重复和不一致
  • API的一些参数和返回值,同一个参数/返回值可能存在类型差异;由于API需要向前兼容,修改API有成本

除此之外,还有其他工程上的约束:

  • 不能影响现有的API,所有的事情只限于iOS端的修改
  • 代码即文档,因为没有精力维护文档
  • 对不同Model的持久化方式作迁移
  • 避免写大段枯燥的Model的序列化/反序列化代码
  • 没有时间造出足够成熟、健壮可重用的组件及撰写文档

上述的问题都是长期存在且需要解决的,否则严重影响开发效率及代码质量。11年的时候我还在做社交游戏的时候,设计并实现了一套简单的基于Objective-C Runtime的数值表Model结构及转换工具(Model<=>csv)供数值策划使用。但想写出一套成熟的方案还是有一些距离,而且也没有资源和时间作维护、测试和文档。

顺着这个思路找到了JSONModel和Mantle,前者刚刚1.0,后者在Github for Mac中广泛使用且社区更成熟(甚至Slack上有channel),所以成为了更好的选择。

事实也证明这个选择是对的,6.0上线后,crash率比之前的版本有显示的降低,并且Mantle相关的crash占总crash的比率不到3%,大可以直接用在大型的产品上。

除了成熟稳定,Mantle基本解决了我们遇到了的所有问题。下面具体介绍一些通用性Mantle使用经验,基本的使用方法请直接移步Mantle的README。

Property名称转换

由于API使用的开发语言与iOS所使用的Objective-C是截然不同的,所以可能将一些保留关键字作为property的名称(如id),或者不小心override掉基类的属性(如description)。还有可能API中使用了一个很糟糕的名称,或者使用了不符合Objective-C命名规范的名称,这些我们都需要作转换。

只需要实现MTLJSONSerializing protocol并在+JSONKeyPathsByPropertyKey方法中定义好新旧名称的映射关系即可,Mantle会在序列化及反序列化时对属性名进行自动的转换。

     
1
2
3
4
5
6
7
8
9
     
+ ( NSDictionary *)JSONKeyPathsByPropertyKey {
return @{
@"identifier": @"id",
@"displayDiscription": @"description",
@"thisIsANewShit": @"newShit",
@"creativeProduct": @"copyToChina",
@"betterPropertyName": @"m_wired_propertyName"
}
}

好了很多吧?没错,只需要定义一次名称的映射关系就可以了,Mantle负责model与JSON之间的双向转换。不需要将这种逻辑写得到处都是,并且还得维护它的一致性。

Property的类型映射

iOS中处理URL使用的是NSURL类型,但JSON只支持基本的字符串,Mantle可以自动帮你转换成NSURL。

     
1
2
3
     
+ (NSValueTransformer *)URLJSONTransformer {
return [NSValueTransformer valueTransformerForName:MTLURLValueTransformerName];
}

NSValueTransformer负责在不同类型间进行双向转换,请读者研究一下Mantle的实现方式。在此前提下,留给读者一个问题(其实这是一个真实的故事,类似的故事还有很多,详见iOS应用开发之十大坑队友):

假设我们有一个entity,名字且叫KTVConcreteEntity吧,它有一个属性名字叫entityID,类型是NSInteger。问题来了,entityID可能在另外一个API的response中是字符串类型,在不直接修改Mantle的源码的前提下怎么搞?欢迎在下方留言讨论。

空标量异常

有的时候API的response会有空值,比如copyToChina可能不是每次都有的,JSON是这样儿的:

     
1
2
3
     
{
" copyToChina": null
}

Mantle在这种情况会将newShit转换为nil,但如果是标量如NSInteger怎么办?KVC会直接raise NSInvalidArgumentException。

Mantle是基于KVC给property赋值的,KVC提供了- (void)setNilValueForKey:(NSString *)key方法,让我们为nil指定一个合理的替代值,我们来看一下此方法的解释:

Invoked by setValue:forKey: when it’s given a nil value for a scalar value (such as an int or float).
Subclasses can override this method to handle the request in some other way, such as by substituting 0 or a sentinel value for nil and invoking setValue:forKey: again or setting the variable directly. The default implementation raises an NSInvalidArgumentException.

对于标量来讲,多数情况下合理的值即为0,我们来看下代码:

     
1
2
3
4
5
6
7
8
     
@interface MTLModel (KTVNullableScalar)
@end
@implementation MTLModel (KTVNullableScalar)
- ( void)setNilValueForKey:( NSString *)key {
[ self setValue:@ 0 forKey:key]; // For NSInteger/CGFloat/BOOL
}
@end

问题完美解决,再也不需要到处写无聊的if/else了。

其它重要特性

Mantle为我们带来的方便不胜枚举:

  • 实现了NSCopying protocol,子类可以直接copy是多么爽的事情
  • 实现了NSCoding protocol,跟NSUserDefaults说拜拜
  • 提供了-isEqual:和-hash的默认实现,model作NSDictionary的key方便了许多
  • 简单且把一件事情做好,不掺杂网络相关的操作

如此强大优雅的设计,让我不得不向Github的工程师们致敬!

写在后面

篇幅所限,只介绍了几个典型的问题,欢迎大家讨论。但如果你的App的代码规模只有几万行,或者API只有十几个,或者没有遇到我们这些遗留问题,我建议还是不要引入了,杀鸡用指甲刀就够了,杀不动多磨磨找准要害。Anyway,Mantle的实现和思路是值得每位iOS工程师学习和借鉴的。

附小广告一则:唱吧iOS团队诚招iOS工程师,推荐成功即奖励6000元现金或iPhone 6一部,详见这篇blog。


原文地址:http://www.iwangke.me/2014/10/13/Why-Changba-iOS-choose-Mantle/

感谢原作者。

基于Simulink的无迹卡尔曼滤波(UKF)SOC高精度估计仿真 本文介绍了基于Simulink的无迹卡尔曼滤波(UKF)在电池SOC高精度估计中的应用。通过无迹变换替代传统EKF的线性化过程,UKF显著提升了SOC估计精度,在强非线性工况下误差可控制在0.5%以内。文章详细阐述了UKF的核心原理,包括Sigma点生成、状态预测和观测更新等关键步骤,并基于Thevenin等效电路模型构建了完整的UKF SOC估算系统。通过Simulink建模和仿真验证,展示了UKF在大电流脉冲、变温工况等复杂场景下的优异性能,其动态响应时间小于30ms,长期累积误差低于0.7%。研究为储 阅读详情

相关推荐

Dify+firecrawl:一个超好用的网页转Markdown API,打造你的第一个能检索爬虫RAG知识库的聊天机器人

Firecrawl是一个超简单的API服务——你扔给它一个URL,它就能把整个网站(包括子页面!)的内容自动抓下来,并且转换成干净、易读的Markdown格式。不用配置网站的站点地图,不用写爬虫规则,API调一下,数据直接到手。接下来我们一起本地部署吧!

2501_91673550的博客 2988

Mantle--国外程序员最常用的iOS模型&字典转换框架

Mantle简介 Mantle是iOS和Mac平台下基于Objective-C编写的一个简单高效的模型层框架。 Mantle能做什么 Mantle可以轻松把JSON数据、字典(Dictionary)和模型(即Objective对象)之间的相互转换,支持自定义映射,并且内置实现了NSCoding和NSCoping,大大简化归档操作。 为什么...

weixin_34307464的博客 259

Hive数据迁移

【迁移背景】 本次需要将老集群的hive数据(共30多张表)迁移至新集群中。 老集群版本为CDH5.13,未启用kerberos; 新集群版本为CDH5.14,启用了kerberos。 由于cloudera官方文档说明,在5.x的版本不支持从未启用kerberos的集群与启用了kerberos的集群之间的数据复制。因此无法通过bdr方式进行数据同步。于是采用手工方式进行测试验证。 第一步...

wangkuangood3200的专栏 469

deit_base_distilled_patch16_224.fb_in1k配置详解:从config.json参数到模型性能调优

deit_base_distilled_patch16_224.fb_in1k是一个基于Transformer的高效图像分类模型,通过蒸馏技术提升了性能表现。本文将详细解析其配置参数、环境搭建及性能调优方法,帮助新手快速掌握模型使用技巧。 ## 核心配置参数解析 ### 基础架构参数 `config.json`文件定义了模型的核心架构,其中`architecture`字段指定模型类型为`dei

gitblog_00041的博客 569

Windows下快速搭建MSYS2开发环境(含GCC与MinGW配置)

本文详细介绍了在Windows系统下快速搭建MSYS2开发环境的完整流程。通过使用pacman包管理器,可以便捷地安装GCC编译器与MinGW-w64工具链,并配置系统环境变量。文章还涵盖了从基础安装、系统更新到编译开源项目的实战指南,帮助开发者高效构建原生Windows程序,显著提升C/C++开发效率。

weixin_29213827的博客 538

手把手教你用Origin拟合真应力-真应变曲线:从数据到加工硬化指数n的完整流程

本文详细解析了如何使用Origin软件拟合真应力-真应变曲线并计算加工硬化指数n的全流程。从数据预处理、曲线绘制到Hollomon方程拟合,逐步指导材料科学研究人员完成实验数据分析,帮助准确评估金属材料的力学性能与强化特性。

view3的博客 710

iOS mantle 使用

model中带数组的情况 #import <Mantle/Mantle.h> #import "MantleModelCommonHeader.h" #import "MessageModel.h" @interface MessageListModel : MTLModel <MTLJSONSerializing> @property (nonatomic, s...

NOHACKCC的专栏 728

手把手教你用TP4056和PMOS管搭建锂电池自动切换电路(含元器件选型指南)

本文详细介绍了如何使用TP4056和PMOS管搭建锂电池自动切换电路,包括核心架构设计、元器件选型指南和PCB布局优化。通过智能充电算法和电源路径切换模块,实现外部供电与锂电池的无缝切换,提升便携式设备的电源管理效率。

julia4scientist的博客 887

iOS处理json,序列化和反序列化

如果需要做类型转化,比如string类型转换为Date类型,可以使用NSValueTransformer来实现,这个时候需要在自定义的Model添加dateValueTransformer方法,运行的时候会自动调用dateValueTransformer方法完成类型转换。上面这个例子演示了Mantle的属性转换,嵌套类型,集合类型的使用方法,需要注意的是每个Model都需要继承自MTLModel类,并且实现MTLJSONSerializing协议。Mantle 允许你自定义属性值的转换。

零丁若叹 1354

宋浩线性代数笔记

Miao-A-SongHao-Linear-Algebra-Notes bilibili 宋浩老师 “惊叹号” 系列 《线性代数》网课 笔记及时间点目录 Github项目地址:https://github.com/cy69855522/Miao-A-SongHao-Linear-Algebra-Notes ???? 前言 我发现吧,线代没记笔记真不行。 浩浩学习,天天向上。数学网课推荐????宋浩老师的免...

Knife丶小刀博客 4万+

微调大模型如何准备数据集——常用数据集,Alpaca和ShareGPT

在大模型微调中,我们一般使用Alpaca 和 ShareGPT和两种格式的数据集。

Science prince的博客 1095

iOS开源库源码解析之Mantle

来自Leo的原创博客,转载请著名出处我的StackOverflow这个源码解析系列的文章 AsnycDispalyKit SDWebImage Mantle(本文) AFNetworking(3.0) MBProgressHud SwiftJSON MagicRecord Alamofire 前言iOS开发中,不管是哪种设计模式,Model层都是不可或缺的。而Model层的第三方库常用的库有以下几个

Leo的专栏 8510

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

iOS的Mantle实战

公司项目之前的model层代码是我使用JSON工具直接生成Objective-C代码的,当时还是觉得相当省事的,毕竟我经历过无model层的NSDictionary“黑暗”时期。但是随着项目的推进,问题开始慢慢显现出来。   于是,在一个多月前,我在Objc.io上看到提及了Mantle,花了一点时间看了一下,决定先在分支上全套改用Mantle。使用了一段时间,性能没造成什么瓶颈,稳定

afdl9999的专栏 1239

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

为什么唱iOS 6.0选择Mantle

近来的iOS的6.0版本号已经成功上线了。18人月的投入,2500个commit,几十万行的代码改动。唱吧iOS已经从内至外焕然一新,感谢一起并肩作战的小伙伴们。 6.0一个非常重大的改动就是基于Mantle重建(新建)了Model层。这里不正确Mantle作很多其它介绍。仅仅分享一下使用Mantle的决策及运行过程。 我们遇到的问题 唱吧是一款上线2年多的App,产品形态的演进和迭...

weixin_33845881的博客 124

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Mantle的优缺点

简要分析   先来简要分析一下各种构建model层方法的优点和缺点:   一、工具生成model   优点:   1、简单易用,新手也可以10秒上手   2、有一定的容错代码   3、代码生成相对工整和规范,部分工具还可以选择是否使用ARC   4、生成简单model耗时少   缺点:  

Linlei的专栏 1442

关于Mantle使用个人的一些见解

前一个月,我接触到了Mantle,由于项目采用的是MVC的设计模式,选用好的model也是至关重要的。先介绍下Mantle的使用吧。 首先定义好数据模型: @property (nonatomic, copy) NSString *address; @property (nonatomic, copy) NSString *contact_info; @p...

weixin_30652271的博客 180

苹果召开新品发布会 - iOS移动开发周报

新闻\\《苹果召开新品发布会》:北京时间10月17日凌晨1点,苹果在美国加州库比蒂诺总部Infinite Loop园区的Town Hall大会堂如期召开了主题为“久违了(It’s been way too long)”的新品发布会。这也是继苹果iPhone6、iPhone 6 Plus正式发布后,苹果在今年秋季举办的第二场大型发布会。在此次发布会上,苹果正式发布了iPad Air 2、iPad m...

cpongo5 213

一些 iOS 常用的第三方库

网络通信 AFNetworking轻量级的通讯类库,使用非常简单。建议更新到最新版,前几天看新闻说之前有个逻辑性的bug https://github.com/AFNetworking/AFNetworking MKNetworkKit最近做的不错的一个通讯类库,具有AFNetworking和ASIHTTPRequest双方的优点,甚至功能更丰富...

anqi0114的博客 175
上一篇: Objective-C Runtime 运行时之一:类与对象
下一篇: IOS开发----CMDeviceMotion陀螺仪的使用
「已注销」
博客等级 码龄12年 28粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值