iOS混合开发库(GICXMLLayout)二、功能、架构介绍

930 阅读9分钟

如果你已经下载了项目源码,并且在模拟器或者真机中运行过了,你会发现GIC还是提供了较多的功能的,通过这些功能基本能够满足大多数的开发需求了。

这篇文章主要分享下GIC的整体功能以及架构设计介绍。

GIC布局系统以及UI元素是基于Texture实现的,数据绑定中的单向和双向绑定是基于RAC实现的,而动画是基于PopAnimation实现的。可以说GIC是站在巨人的肩膀上诞生的。

因为GIC布局系统以及UI元素是基于Texture实现的,因此GIC天生在性能上就有优势,同样支持background 布局和渲染(区别于UIView只能在UI线程调用),就算是在像iphone4那样的机器上也能流畅的运行(你可以直接将项目中的Sample在真机上运行体验)。事实上,在实际的开发过程成,你会发现,GIC即发挥了Texure的性能优势,又带来了使用XML进行简单便利的UI布局体验,可以这么说,GIC之于Texture就像Marsonry之于Autolayout

架构图

GICXMLLayout 整体架构图

从上面的架构图中可以看出,整个GIC分为三个模块,GICCorebehavior 扩展JavaScript。其实严格来说,应该只有两个模块,GICCoreBehavior,JavaScript其实是behavior的一个扩展而已。

这里单独介绍下什么是BehaviorBehavior的中文意思是行为,你可以理解为通过Behavior来赋予元素的某个行为。比如:

一个list(UITableView)本身不具备下拉刷新能力的,但是你可以通过Behavior将下拉刷新的功能单独封装成一个behavior,然后赋予list下拉刷新的能力。或者就像架构图上设计的,GIC中的元素本身不支持JS调用的,但是通过Behavior扩展就能具备执行JS脚本的能力。

总的来说就是将某一特定的功能封装成behavior,然后将这个behavior添加到某个元素上的时候,该元素就具备了这个行为能力。因此,你可以通过自定义自己的behavior来实现功能上的扩展。

从上面的架构图中还能发现,除了XML解析数据转换以外,其他的都属于自定义元素GIC的核心功能就是基于XML来实现以前需要coding才能实现的功能,因此一切元素都是围绕着XML来实现的 ,更进一步的可以将XML理解为是一个map工具,将XML的节点元素映射到native某个Class的工具。

下面一一介绍下各个子模块的功能和特点:

一、GICCore模块

1. 解析模块

  1. XML解析

    这里主要是负责根据XML每个节点的名称,解析成对应Native中的某个Class,然后将该节点的属性转换成对应Class属性的数据类型。

  2. 数据转换

    我们都知道XML中的属性都是字符串形式的,虽然我们能够通过元素名称从而找到对应Native的Class,但是每个Class的属性的数据类型是不一样的,有的是int、有的是string、有的是UIColor、有的是UIFont等等,这些不同的数据类型就需要有专门的转换器来将string转换成对应的数据类型,这样在XML解析的过程中,可以通过不同的数据转换器,将XML中的属性转换成对应该元素native属性的数据类型。

通过XML解析数据转换,就能将一个XML文件准确的映射到Native的Class,并且设置对应的属性。

这样一来,整个的XML解析模块就清晰了,剩下的事情就是定义元素的事情了。

2. GIC提供的核心元素。

  1. UI元素

    UI元素其实就是能够显示的元素,比如:lableimagelistcanvas等等,也包括其他通过自定义扩展实现的UI元素。GIC自带的UI元素虽然有限,但是通过各种组合也能实现复杂的UI布局。

  2. 布局系统

    GIC中的布局系统是基于Texture实现的,每一种布局面板对应于Texture中的某个LayoutSpec,而GICTexure的基础上进行了进一步的封装,使得在使用XML进行布局的时候更加的简单方便。GIC也提供了类似前端FlexBox那样的布局面板,你可以通过组合不同的布局面板来实现复杂的UI布局。

  3. 数据绑定:

    数据绑定功能可以说是贯穿整个GIC的功能,任意元素的的任意属性都可以通过绑定来赋值。GIC中的数据绑定是基于JavaScriptCoreRAC来实现的,JavaScriptCore主要是用来实现计算绑定的JS表达式,而RAC主要是用来实现单向、双向绑定功能的。数据绑定的语法类似于前端的VUE,使用{{}}两对大括号来表示数据绑定,数据绑定的表达式支持JS,也就是说你可以直接在数据绑定的表达式中动态的计算。

  4. 模板:

    模板的功能类似于前端的tempalte,是参考Vue中的component功能开发的,因此也具有模板嵌套占位等功能。你可以将一些具有相同UI布局的XML代码单独作为一个模板,然后在任何地方引用这个模板,这样的功能类似于Native中的自定义UIView的功能。

  5. 样式:

    样式的功能类似CSS,只是使用XML来描述,你可以利用样式为整个APP提供类似主题的功能,只需要定义不同的样式文件即可。

  6. behavior:

    行为的概念在本编开头已经介绍过了,就不再过多介绍了

以上6个功能是GIC提供的核心功能,构成了整个GIC的基础。其他的功能都是基于这6大功能实现的。

二、behavior扩展

GIC中的很多的功能都是基于behavior来实现的。本篇开头也提到了,behavior可以为任意元素赋予behavior所拥有的功能,这样一来,可以很大程度的对实际项目中的某些功能进行解耦。

目前GIC提供的功能中,有如下几个是通过behavior实现的,分别是。

  1. 事件:

    目前GIC针对所有的UI元素都提供了tapdouble-taptouch-begintouch-movetouch-end共5个触摸事件,而其他的事件都属于自定义事件,比如:item-select提供了cell选择事件,开发者也可以为元素添加任意的自定义事件。在XML中可以直接以js表达式或者对应ViewModel中的方法名称来绑定事件,当事件触发以后,GIC会自动执行JS表达式或者调用ViewModel中的方法。

  2. 指令:

    指令这个概念其实是从前端的VUE中借鉴过来的,目前GIC提供了两个指令,分别是foriffor指令是用来从数组中动态循环创建元素并且自动将数组的item作为元素的数据源,而且会自动监控数组的改变然后自动做出相应的操作,比如当数组删除item的时候for指令会自动删除该item对应的元素等等,而这一切无需你手动去处理,for指令会自动帮你处理。而if指令会根据条件表达式的true、false来动态的添加、删除元素。

  3. 动画:

    GIC的动画是基于PopAnimation开发的,理论上支持任意属性的动画,而GIC的文档中在列出属性的同时也给出了该属性是否支持动画。你现在可以直接使用XML来写动画了,GIC的动画也提供了不同的触发方式,最新版已经支持通过任意事件来触发动画了。

  4. 脚本:

    事实上脚本并不是单指JavaScript,只是当前GIC只实现了对JavaScript的支持而已,从架构图上可以看出,脚本是独立于GICCore以外的一个单独的功能,理论上可以支持任意的脚本语言,比如:LuaPythonDart,只需要提供相应的脚本解析器以及提供相应的脚本入口即可。而GIC中对JavaScript的支持,也是独立于GICCore单独开发的。

三、JavaScript

GICJavaScript的支持是基于JavaScriptCore这个framework实现的,而JavaScriptCorewebkit的一个分支,而且还是开源的,具备跨平台的能力。因此,在Android上也能实现一样的功能。

目前JavaScript模块分三个子模块,分别是:

  1. elementsAPI:

    该模块的功能是将native的元素,转换成可以直接被JS调用的JSValue,这样一来可以直接使用JS来给给该元素设置属性或者删除该元素等等。

  2. JSAPI扩展:

    JavaScriptCore本身包含的JSAPI是有限的,一些常用API比如:console、XMLHttpRequest、setInterval等等是没有的,因此需要自己去添加相应的JSAPI的支持,GIC已经提供了部分常用的API的实现,其他一些API开发者可以自己实现。

  3. nativeAPI:

    这个模块目前并没有直接放入GIC的代码中,原因是担心一旦GIC直接包含这部分的代码会导致苹果的封杀。在技术上,JS直接调用Native的API是可以实现的,而且也并不是很复杂,这个模块的代码会作为一个独立的代码共享出来,如果你想要这样的功能,只需要将该模块的代码添加到你的项目中即可。这样你就拥有了可以直接使用JS调用NativeAPI的能力。但说实话,这样的功能在GIC中其实不是必须的,因为首先GIC的XML布局已经是动态的了,而且还支持JS来写逻辑,另外还提供了丰富的自定义功能,因此在实际的开发中,对于JS调用NativeAPi这样的功能就显得不是那么的急需了。

总结

以上是对GIC提供的功能的一个大概性的介绍。详细的文档可以直接在线浏览