iOS组件化-入门

105 阅读4分钟

什么是组件化

当我们公司的业务在不断增长的同时,我们相应的app的业务和功能也在不断的增长;当app的体量增长到一定的程度的时候,代码维护就变得异常的困难,同时也会增加打包的时间。

那么大家有没有遇到过这样的问题:

  1. 我只是改了某个功能的一点东西,却不得不把整个项目build一遍,上个厕所打个水,回来发现还在building...
  2. 仍然是只改了一点东西,好不容易build完了,发现另外一个功能不能用了
  3. 老板晚上开会说,我们要开发一个新的app,很多功能我们以前的app都有,应该用不了多长时间吧,给你们一周时间...
  4. 同样的功能却使用了不同的实现方式,甚至是不同的语言,当让你来维护的时候,有没有感觉到一丝丝头疼

组件化并不能完全解决这些问题,但是可以让项目的代码更条理,结构更清晰,提高开发效率。

如何开发一个组件

组件我们应该很熟悉了,日常用到的AFNetworking,SDWebImage等等都属于组件。

我们日常使用的这些库的索引一般都是存放在cocoapods的pod repo中,我们需要在podfile文件中引入需要使用的库,然后pod就会去pod repo中查询有没有这个库,如果有,那么就会根据查询到的这个库的podspec文件找到代码具体存放的位置以及其他一些设置。

image.png

上图简单的演示了组件库的查询路线,当然,repo去哪里找代码取决于你的代码存放的路径。

那么,我们先来看看怎么制作一个组件吧。

创建远程索引库

在制作组件之前首先我们需要一个repo,因为我们做的是组件化开发而并非公共库,所以,我们就不使用pod的repo了,在这里我们就用码云来搭建一个自己的代码仓库。

首先,我们在码云中创建一个私有仓库库,得到了私有库的地址:

<https://gitee.com/Tinary/tytestrepo.git>

将远程索引库链接(下载)到本地

创建好私有仓库后,我们打开terminal,使用pod repo add命令将私有仓库的地址添加到pod repo 的列表中:

pod repo add tytestrepo <https://gitee.com/Tinary/tytestrepo.git>

这样就能将我们之后创建的组件库推到这个地址中了。当然,别忘记把命令中的仓库名称和地址改成你自己的。

在本地创建一个组件

pod lib create <pod库名字>

执行结果:

Untitled.png

这样,我们就创建了一个名为 TYTestPodA 的组件。

修改内容

我们简单的给刚创建的TYTestPodA添加了一个输出信息的功能。

创建TYTestPodA的文件,并将其放置于当前组件的TYTestPodA/TYTestPodA/Classes路径下。

现在,我们的Classes文件夹下的结构是这样的:

Untitled.png

文件内的内容:

@interface TYTestPodA : NSObject
- (NSString *)showPodAInfo;
@end
@implementation TYTestPodA
- (NSString *)showPodAInfo {
    return @"hello, this is TYTestPodA";
}
@end

修改.podspec文件

podspec文件存储的是我们组件的相关信息,当pod install的时候就会根据组件名和版本信息,去pod repo中查询该组件的podspec信息,进而拉取相关代码。

#
# Be sure to run `pod lib lint TYTestPodA.podspec' to ensure this is a
# valid spec before submitting.
#
# Any lines starting with a # are optional, but their use is encouraged
# To learn more about a Podspec see <https://guides.cocoapods.org/syntax/podspec.html>
#
Pod::Spec.new do |s|
  s.name             = 'TYTestPodA'
  s.version          = '0.1.0'
  s.summary          = 'A short description of TYTestPodA.'
# This description is used to generate tags and improve search results.
#   * Think: What does it do? Why did you write it? What is the focus?
#   * Try to keep it short, snappy and to the point.
#   * Write the description between the DESC delimiters below.
#   * Finally, don't worry about the indent, CocoaPods strips it!
  s.description      = <<-DESC
TODO: Add long description of the pod here.
                       DESC
  s.homepage         = '<https://gitee.com/Tinary/TYTestPodA>'
  # s.screenshots     = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  s.author           = { '这里是作者的名称' => '这里是邮箱地址' }
  s.source           = { :git => '<https://gitee.com/Tinary/TYTestPodA.git>', :tag => s.version.to_s }
  # s.social_media_url = '<https://twitter.com/><TWITTER_USERNAME>'
  s.ios.deployment_target = '10.0'
  s.source_files = 'TYTestPodA/Classes/**/*'
  # s.resource_bundles = {
  #   'TYTestPodA' => ['TYTestPodA/Assets/*.png']
  # }
  # s.public_header_files = 'Pod/Classes/**/*.h'
  # s.frameworks = 'UIKit', 'MapKit'
  # s.dependency 'AFNetworking', '~> 2.3'
end

提交

我们在码云创建一个用于存放TYTestPodA组件的仓库,将我们刚刚创建并修改好的TYTestPodA组件提交到这个仓库。

git add .
git commit -m "add file"
git remote add origin <远端pod库地址:https://gitlab.com/xxx.git>
git push -u origin master

打tag并提交tag到origin

git tag 0.1.0
git push --tags

验证本地spec文件是否有误

pod lib lint

验证远程spec文件是否有误

pod spec lint

如果模拟器验证不通过的话,可以在命令后面添加--skip-import-validation

出现TYTestPodA.podspec passed validation.说明我们验证已经通过了。

接下来,就需要我们上传.podspec索引文件到索引库 pod repo push <索引库名称> <.podspec文件名称>

pod repo push tytestrepo TYTestPodA.podspec --allow-warnings --use-libraries --verbose

上传完成后打开我们的repo仓库,发现podspec文件和版本号已经被推送到了repo中,后续其他项目需要使用TYTestPodA这个库就可以去这个repo中拉取了。

Untitled.png

最后我们在项目工程中测试一下,在项目工程的Podfile中添加我们私有库的source。

Untitled.png

然后使用pod install安装组件

Untitled.png

测试一下,AppDelegate中导入#import <TYTestPodA/TYTestPodA.h>,并调用TYTestPodA的showPodAInfo方法。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Override point for customization after application launch.

    TYTestPodA * poda = [[TYTestPodA alloc] init];

    NSString *info = [poda showPodAInfo];

    NSLog(@"%@", info);

    return YES;

}

成功打印信息,到此,简单的制作一个组件并在项目中使用该组件的流程就完成了。

Untitled.png