iOS应用模块化的思考及落地方案(一)模块的划分及模块化工作流程
1.0 什么是模块化
很多关于重构
及设计模式
的介绍中,经常提到的几个词语是复用
及解耦
。
模块化之所以被提出,也更多是为了解决这几个问题。
复用
可以减少重复造轮子的情况,很容易理解的是,我们经常使用的github上的第三方框架,比如,AFNetworking等,有了这些组件,我们就不需要再写一遍了。
解耦
可以减少类或文件之间的关联,如果一个类引用了其他10个类,那么当我们看到这个类或修改这个类的时候,我们同时需要关注另外10个类,了解它们与本类的关联情况。如果你的类,没有与其他任何类关联,你在阅读代码的时候,完全可以忘记其他代码的存在,只看这一个文件就够了。
我们可以看出,低耦合
的系统,能够将无数简单的模块,组成复杂的工程。复用
很明显能够提升工作效率,解放生产力。
这样一来,你的系统是简单的,清晰的,当你重构或修改系统的时候,可以不必有任何顾虑。
而实现低耦合
和可复用
的手段,往往就称为模块化。
在实际开发中,模块往往被定义为能够独立实现单一任务的代码单元。
从代码角度讲,一个功能,一个文件,一个类,甚至一个函数,都可以成为一个模块。
除了上述优点之外,模块化之后,每个模块可以单独开发,单独测试,也更容易做内部代码的权限管理。
上面已经说过,整个系统都是由不同的模块构成。那么问题的难点就在于,如何定义模块的边界。
2.0 模块的划分及通信
在客户端实际开发中,根据模块的使用方式,可以大致分为2种。
第一种,提供非常基础功能,会频繁地被其他模块引用,其他模块可以直接引入这些模块的api进行调用。比如:网络模块,常用工具类,布局,图片,其他依赖的第三方框架。
第二种,提供有价值的产品功能,更多的是页面的展示接口,它从来不被别的模块直接引用,更多地通过异步的方式来进行通信(使用路由)。比如:会员模块,付费模块,短视频模块等等。
另外,除了这两种模块之外,还有一种模块既会被其他模块频繁地引用,也会提供页面的展示接口。比如:登陆,收藏,关注等功能。这种模块需要为其他模块提供数据及修改接口,有时候还需要展示UI。
其实对于第三种模块来说,可以根据数据和展示,拆分为2个模块:一个模块用于对外部提供数据,可以被其他模块直接引用;另一个模块用于通过异步的方式进行页面的展示。
3.0 iOS模块化的实践方案
3.1 模块化工作流程
iOS中的模块化,不同的模块是通过动态库/静态库的方式引入到主工程中的。
动态库和静态库的区别无需多说,可根据需要自行选择。
cocoapods是一个非常优秀的模块管理工具。
我们使用cocoapods来管理不同的模块时,代码可以以3种存在形式出现,分别是:源码,静态库,动态库。
所以在模块化之前,我们需要提前进行的工作有:
- 安装cocoapods
- 建立pod私有库,用来存储我们所有模块的podspec文件
我们创建一个新模块工作流应该是这样的:
- 建立一个新工程,修改必要设置
- 建立Podfile文件,添加依赖,然后执行pod install安装依赖
- 开始开发工作,开发过程中,你可能需要建立一个Demo工程或者Demo target用于在开发过程中,测试你的静态库api
- 编写单元测试
- 测试通过后,你需要将代码提交到git中,并且打一个tag
- 编写podspec文件
- 检查podspec文件的正确性
- 使用pod repo push命令将podspec文件推到pod私有库中
- 如果其他模块想要引用这个模块,按照pod标准使用方式安装依赖即可
3.2 可能遇到的问题
在上述流程中,可能遇到的问题有:
- podspec文件怎么写?
- podspec文件提交和更新需要怎么做?
- Podfile文件怎么写?
- 如果我开发的模块依赖了我们之前开发的其他的模块该怎么处理?如果我依赖的模块也需要修改,应该怎样处理?
- 产生循环依赖怎么办?A依赖B,B又依赖A。
- 怎样处理图片等资源文件
- 如何进行OC与swift的混编
- framework如何编译,如何减肥,如何合并
4.0 流程自动化
我们可以看到,创建模块化的过程流程比较多,涉及的技术也很多:cocoapods,Xcode设置,资源管理,Swift&OC编译管理,静态库接入方式等等。
其中很多技术内容其实并不常用,在开发过程中,我们遇到问题后,即时查阅文档解决,过了一段时间,遇到同样的问题可能还需要再查阅。
而且,不同的人在实践过程中,可能会遇到相同的问题,每个人都需要解决一次。
流程过多,还容易因为误操作而产生错误,这种问题很难解决,往往遇到就会花费大量时间处理。
我们再回头看一下工作流程,其实很多工作都是固定不变的,每次创建新模块都是重复同样的过程,因此这部分流程我们可以通过自动化脚本自动完成。
我们哪些工作可以使用脚本完成呢?
- 创建
模块工程
及Demo
工程,自动设置里面的Build Setting
选项,并使用.xcworkspace来管理 - 部分内容根据用户输入,自动创建
podspec
文件,并检查其正确性 - 根据用户输入的依赖模块,自动创建不同工程的
Podfile
文件,并使用pod install
安装依赖 - 管理模块目录结构,脚本能够方便的对模块进行增删改查
- 如果某个模块依赖的是我们自己开发的其他模块,那么被依赖的模块会以
local path
的方式引入到工程中,这样我们可以在当前模块的工程中直接修改依赖模块的代码并进行测试,不需要打开多个工程。开发完成后,分别进行提交。 - 自动安装脚本所依赖的软件和环境
- 记录已经push到私有库的模块,方便处理多依赖模块的开发
- 开发完成后,使用脚本一键推送到pod库中
- 对已经在pod库中的模块进行二次开发时,可以一键拉取工程并安装所有依赖
完成上面的功能后,我们可以发现:
- 对于全新的模块,我们可以使用脚本,一键创建工程,然后就可以进行业务开发了,开发之后,只需要再执行一个脚本,就能够推送到私有库中,不需要了解cocoapods和Xcode设置的任何细节。
- 对于二次开发的模块,我们同样适用脚本,一键拉取工程及所有依赖,仅仅关注业务开发即可。开发完成后,同样使用脚本一键推送到私有库中。
–完--
- iOS应用模块化的思考及落地方案(一)模块的划分及模块化工作流程
- iOS应用模块化的思考及落地方案(二)模块化自动构建工具的使用
相关文章:

Swiper 用法
部分常用API ininialSlide: 2, //起始图片切换的索引位置(起始从0开始,默认为0) autoplay: 3000, //设置自动切换时间,单位毫秒 speed: 1000, //设置滑动速度 continuous: true, //无限循环的图片切换效果 disableScroll: true, /…
node/js 漏洞_6个可用于检查Node.js中漏洞的工具
node/js 漏洞Vulnerabilities can exist in all products. The larger your software grows, the greater the potential for vulnerabilities. 所有产品中都可能存在漏洞。 您的软件增长得越大,潜在的漏洞就越大。 Vulnerabilities create opportunities for expl…

发现一个浏览器很奇怪的问题
浏览器有8个请求状态为pending时,在另一个tab中,请求就发布出去了,一直是stalled。直到pending状态变成了cancled状态。 试了360浏览器(谷歌内核)和chrome浏览器,都是这样。 具体的原因待深究 参考…

wamp配置虚拟主机
因为wampserver的php版本一直是5.x版本;因此转投xmapp用了一段时间; 意外发现wampserver3更新了;php也终于更新到7了; 果断还是决定回到wampserver的怀抱; 然后有意外的发现了wampserver3有了新功能;可以方…

iOS应用模块化的思考及落地方案(二)模块化自动构建工具的使用
1.0 iOS模块化中的问题 前文已经介绍了模块化的流程及一些常见的问题,我们在这里再次总结一下。 在工作中,当我们开始一个新项目的时候,最先考虑的就是模块化工作。 模块化工作的想法是很美好的,可是执行过程中会遇到很多的问题…

aws fargate_我如何在AWS Fargate上部署#100DaysOfCloud Twitter Bot
aws fargateAfter passing my last certification, I asked myself how much time I spent studying cloud computing.通过上一份认证后,我问自己自己花了多少时间研究云计算。 More than 100 days!超过100天! It also made me realize two things:这也…

think in Java 第五章之垃圾回收类型
1.引用计数: 每个对象都含有一个引用计数器,当有引用连接至对象时,引用计数加1,当引用离开作用域或被置为null时,引用计数减1. 缺陷:在对象循环引用时,存在“对象应该被回收,引用计数…
Yii 错误页面处理
【错误页面处理】 訪问一个错误的控制器 訪问一个错误的方法 有些控制器和方法禁止訪问 以上訪问会提示错误信息 404 403 以上错误信息是不方便给外边用户看到的。 1. 安全隐患 2. 用户体验不好 错误信息在site/error这个地方定义的。如今我们要自己定义错误页面来显示我们的错…

设置RGBColor
#define kUIColorFromRGB(rgbValue) [UIColor \colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]

自学成才翁_作为一名自学成才的开发者从“我的旅程”中吸取的教训
自学成才翁The path of the self-taught developer is tough and filled with uncertainty. There is no straight line from newbie to career programmer. Because of this, I believe all self-taught developers have a unique story to tell.自学成才的开发者之路艰难而充…

67)vector的begin() end() 和 front() back()的区别 rbegin() rend()
1) 2)v1.begin() 和v1.end() 是作为迭代器v1的 第一个位置 和 最后一个元素的下一个位置。 v1.front() 是v1这个动态数组的第一个元素的值 v1.back()是v1的最后一个元素的值。 3) 4)正向和反向的使…

倒置函数reverse的用法
倒置字符串函数reverse:用于倒置字符串s中的各个字符的位置,如原来字符串中如果初始值为123456,则通过reverse函数可将其倒置为654321,程序如下:#include<stdio.h>#include<string.h>void reverse(char s[…

设置tabbaritem的title的颜色及按钮图片
设置title颜色: [[UITabBarItem appearance] setTitleTextAttributes:{NSForegroundColorAttributeName : kUIColorFromRGB(0xb2151c)} forState:UIControlStateSelected]; 设置按钮图片: UIImage *commonImage [UIImage imageNamed:[NSString strin…
helm部署仓库中没有的包_Kubernetes的Helm软件包管理器简介
helm部署仓库中没有的包Before we dive into the Helm package manager, Im going to explain some key concepts to deploying any application anywhere. Ill also give you a brief introduction to Kubernetes terminology.在深入研究Helm软件包管理器之前 ,我将…

mem 族函数的实现
1.void * memcpy ( void * dest, const void * src, size_t num ); 头文件:#include <string.h>memcpy() 用来复制内存,memcpy() 会复制 src 所指的内存内容的前 num 个字节到 dest 所指的内存地址上。memcpy() 并不关心被复制的数据类型ÿ…

快排递归非递归python_Python递归神经网络终极指南
快排递归非递归pythonRecurrent neural networks are deep learning models that are typically used to solve time series problems. They are used in self-driving cars, high-frequency trading algorithms, and other real-world applications.循环神经网络是深度学习模型…

我的hadoop学习之路
Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上。 Hadoop的框架最核心的设计就是:HDFS和MapRedu…

日期处理工具类 -【二】
1、返回本周的第一天(周日为每周第一天) 1 /**2 * 返回本周的第一天(周日为每周第一天)3 * return4 */5 public static String getTheFirstDayOfThisWeek(){6 SimpleDateFormat format new SimpleDateFormat("yyyy-MM-dd");7 Calendar cal Calendar.get…

超越对手pdf_如何创建一个超越竞争对手的移动应用
超越对手pdfThe amount of time people spend on their mobile phones has increased over the years, and so has the number of people using mobile devices.多年来,人们在手机上花费的时间增加了,使用移动设备的人数也增加了。 It’s safe to say t…

vue路由对象($route)参数简介
路由对象在使用了 vue-router 的应用中,路由对象会被注入每个组件中,赋值为 this.$route ,并且当路由切换时,路由对象会被更新。 so , 路由对象暴露了以下属性: 1.$route.path 字符串,等于当前路由对象的路…

join......on 后面的and 和where的区别
a.where 是在两个表join完成后,再附上where条件。 b. and 则是在表连接前过滤A表或B表里面哪些记录符合连接条件,同时会兼顾是left join还是right join。即 假如是左连接的话,如果左边表的某条记录不符合连接条件,那么它不…

block的运用
cell的.h文件 typedef void(^ActivityCellBlock)(NSString *str); interface ActivityCell : UITableViewCell property (nonatomic,strong) NSArray *labelAry; property (nonatomic,copy) ActivityCellBlock myBlock; -(void)showCell:(ActivityCellBlock)myBlock; cel…

如何在Ubuntu 20.04上设置Python虚拟环境
I recently got myself a “new” laptop – a Lenovo x270 (yay)! And once again I needed to set up a Python virtual environment. So of course I Googled for a solution, just to find my previously written article on the same topic!我最近给自己买了一台“新”笔记…

getURLParameters - 网址参数
返回包含当前URL参数的对象。 通过适当的正则表达式,使用 String.match() 来获得所有的键值对, Array.reduce() 来映射和组合成一个单一的对象。 将 location.search 作为参数传递给当前 url。 const getURLParameters url >url.match(/([^?&])…

block的使用
#import "ViewController.h" /* 使用Block最大的一个好处就是可以在代码块中随时访问外部变量 比如你在A.class类中的某个方法中声明了一段代码块.你可以在代码块中直接对A.class所拥有的成员变量进行调用,并且,通过一定的条件(__block),还可以随时的修改这…

关于二级菜单的问题
大家在做二级菜单的时候经常会碰到鼠标移出一级菜单,二级菜单瞬间消失,根本不给你机会移到二级菜单上,今天分享下怎样解决这个问题。 ①第一种介绍一种简单粗暴的方法,二级菜单的元素放入一级菜单中。 代码地址:http:h…

python打印换行符_Python换行符以及如何在不使用换行符的情况下进行Python打印
python打印换行符Welcome! The new line character in Python is used to mark the end of a line and the beginning of a new line. Knowing how to use it is essential if you want to print output to the console and work with files.欢迎! Python中的新行字…

tomcat启动后 项目运行缓慢,要几十到几百秒不等 怎么样./startup.sh 运行加快
修改 linux系统中 /usr/local/jdk1.8.0_11/jre/lib/security/java.security 借力 好文章。我们新的Linux系统,部署了多个 Tomca,同时重启后t, 每次都阻塞差不多260秒左右。修改之后总的启动时间下降到6-8秒左右。另外,不确定为什么࿰…

转载 C#中使用结构来传递多个参数
C#中当参数超过5个时,建议用结构来传递多个参数。 示例代码如下: 1 public struct MyStruct2 {3 public string str;4 public int number;5 }6 7 class Program8 {9 static void Main(string[] args) 10 { 11 MyStruct myStruct…

xmpp 开源项目选择_如何选择和维护安全的开源项目
xmpp 开源项目选择评估开源项目安全性的一些技巧。 (A few tricks for assessing the security of an open source project.) There is a rather progressive sect of the software development world called the open source community. 在软件开发领域,有一个相当…