您的位置:首页 > 移动开发 > IOS开发

iOS开发笔记之六十六——基于Json的页面动态化方案

2017-07-09 15:09 239 查看
******阅读完此文,大概需要15分钟******

一、需求场景

iOS的动态化一直是工程师们不断致力的方向,尽管JSPatch等动态化方案被苹果否掉之后,类似阿里Weex、点评Picasso这种方案开始成为动态化的另一个重要方向,它们都是通过在App端实现一套JS的引擎,解析js生成Native页面的原理方式,从而达到页面动态化的目的,如果需要复杂的交互App端还需要实现js
bridge,基本能够满足业务动态的需求。

二、基于Json的页面动态化

源码地址:https://github.com/lizitao000/MDJsonView

此方案其实在很久(大概2016年6、7月份),我就开始构思了。那时经常发生某个业务页面,某个重要的信息模块,不断被产品反复的进行样式调整,每次调整,似乎都有它不可拒绝的理由。当时已经实现过通过后端下发Json,客户端实现一个JsonLabel去解析,从而动态生成富文本的方式。源码也包含在https://github.com/lizitao000/MDJsonView中。经过慢慢扩展,形成现在的JsonView。来看一下实现效果:



要想实现这个页面效果,是需要从“后台”下发如下Json文本即可:

{\"type\":\"view\",\"x\":15,\"y\":90,\"width\":340,\"height\":120,\"backgroundColor\":\"#f0f0f0\",\"subViews\":[{\"type\":\"view\",\"x\":10,\"y\":10,\"width\":320,\"height\":100,\"backgroundColor\":\"#ffffff\",\"subViews\":[{\"type\":\"imageView\",\"isNeedCallBack\":1,\"x\":10,\"y\":10,\"width\":70,\"height\":70,\"backgroundColor\":\"#aaaaaa\",\"url\":\"http://v1.qzone.cc/avatar/201503/08/11/30/54fbc2419012c836.jpg%21200x200.jpg\"},{\"type\":\"label\",\"x\":90,\"y\":10,\"width\":50,\"backgroundColor\":\"#ffffff\",\"lineSpacing\":3,\"textList\":[{\"text\":\"厨房乐章\",\"textSize\":16,\"textColor\":\"#000000\"},{\"text\":\"*\",\"textSize\":14,\"textColor\":\"#0f0f0f\"},{\"text\":\"中山公园\",\"textSize\":12,\"textColor\":\"#a0a0a0\"}]},{\"type\":\"label\",\"x\":90,\"y\":35,\"width\":50,\"backgroundColor\":\"#ffffff\",\"lineSpacing\":3,\"textList\":[{\"text\":\"沪港料理\",\"textSize\":12,\"textColor\":\"#a0a0a0\"}]},{\"type\":\"label\",\"x\":145,\"y\":35,\"width\":50,\"backgroundColor\":\"#ffffff\",\"lineSpacing\":3,\"textList\":[{\"text\":\"120元/人\",\"textSize\":12,\"textColor\":\"#a0a0a0\"}]},{\"type\":\"label\",\"x\":90,\"y\":55,\"width\":50,\"backgroundColor\":\"#ffefea\",\"lineSpacing\":3,\"textList\":[{\"text\":\"大众点评排行榜第110位\",\"textSize\":12,\"textColor\":\"#ff6633\"}]}]}]}


三、基本方案原理
由于业务需求只涉及到页面的纯“静态”展示,所以只是封装了JsonView、JsonImageView、JsonLabel这三个控件,当然,这只是起步。而且其实原理和weex、picasso不过是殊途同归而已。只不过,我们直接解析了更加轻量化、更加平台通用化的Json字符串。有人说手动拼写Json,是一件很痛苦的事,其实如果你只是渲染简单的信息展示页面,一切并没有你想象的那么复杂,而且借助下面两个Json格式化工具,将会大大简化这一过程。
http://www.bejson.com/jsoneditoronline/ http://www.bejson.com/zhuanyi/
四、控件的抽象

解析了Json,就会生成了对应的Model对象,每个控件都有自己的Model,而App端的JsonView就是用来根据这个key-Value值,来配置View的属性的。

1、JsonModel

iOS的基础控件都是基于UIView的,所以我们也需要针对UIView的公共属性,抽象出一层顶层JsonModel,这些包括UIView的x、y、width、Height、background等,当然还有很多属性等待着未来扩展。为了区别生成不同的UIView控件,在此model中还有个type属性,根据此字端来判断需要渲染哪种控件,以后所有子ViewModel都要继承此基类Model。

2、JsonView与JsonBaseView

JsonViewModel最重要的一个属性是如下这个字端:

@property (nonatomic, strong) NSArray <MDJsonModel *> *subViews;

这里也是生成嵌套View的关键。JsonBaseView是暴露给业务使用的baseView,解析Json的任务主要在这里进行,里面生成了嵌套JsonView以及各种Json子View。嵌套代码实现是在这里:

- (void)creatJsonSubViewsWith:(MDJsonViewModel *)model inView:(UIView *)rootView;
在这里,我们将初始化了要生成的子View,并将model传进去,进行属性的配置。

3、JsonLabel与JsonLabelModel

JsonLabel是一个可以单独拿出来的富文本组件,通过JsonLabelModel,生成NSMutableAttributedString可以完美实现动态富文本效果。

4、JsonImageView与JsonImageViewModel

JsonImageView采取加载url和本地图片的两种方式,你只需要配置不同的参数即可。但是常常我们需要获取图片这种异步数据的回调消息,所以在此我特意为此做了处理,你在拼写Json时,只是传入isNeedCallBack的值即可。设置了此属性,实现如下回调代码,即可获取异步资源的所有回调信息:

[_jsonView obtainResult:^(MDJsonNotificationResultModel *result) {
NSLog(@"%@",result);
}];
为此,特意封装了MDJsonNotificationResultModel,目前只支持图片的回调信息,后续待扩展。

5、后续扩展

如果你下载了此项目代码,而且此项目代码不能满足你的业务需求时,你需要扩展这些控件或者已有控件的属性,你可以大概遵循下面几个步骤即可完成:

(1)MDJsonMappers中注册,如下:

- (NSDictionary *)allViewMappers
{
return @{
@"view":@"MDJsonViewModel",
@"label":@"MDJsonLabelModel",
@"imageView":@"MDJsonImageViewModel"
};
}
未经注册的view组件是不能被解析的。

(2)继承MDJsonModel,定义自己控件的customModel类型;

(3)继承原生控件,创建customView,解析customModel即可;

五、相关开发工具

前面介绍过,由于直接书写Json,转义Json是一个十分繁琐的过程,一不小心就会解析失败。

在这里http://www.bejson.com/jsoneditoronline/,你可以拼写自己的Json,并结构化它,便于你直观的书写View的层级;其次,写完Json之后,还需要用http://www.bejson.com/zhuanyi/进行转义,才能生成最终的客户端传输Json字符串。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息