iOS开发基础篇iOS进阶组件化

iOS组件化-私有podSpecs

2017-06-21  本文已影响1113人  拂晓的云

最近在学习vue.js的时候发现,vue的组件化的思想对于编写代码是一个非常有用的事情。

首先为什么需要组件化?

下面我列举了一些比较常见的问题

组件化解决问题的思路

利用中间层来做到:只让别的模块对中间层产生耦合,中间层不对其他模块产生耦合
关于这个中间层,这个问题在这里我们就不深究了,大家可以参考蘑菇街解决思路

组件化的目的

我们可以讲每一个模块作为一个组件。并且建立一个主项目,这个朱羡慕负责集成所有组件。
好处:

在这里需要解释一下什么是组件?

一个分类可以是一个组件,一个轮播图也可以是一个组件,一个Controller也是一个组件,甚至一个首页模块(包含内部的所有Controller和业务),都可以是一个组件。

像分类这种被称为基础组件,轮播图这种被称为UI组件,Controller和首页模块这种被称为业务组件。从前到后,从简单到复杂,都是组件。

我们应该怎么做?

在组件化的架构中,有一个主项目用来负责集成其余组件。每一个组件又是一个单独的工程。

组件只需要对外提供服务,通过中间件来调用这些服务。

在这里将通过iOScocoapods私有库的形式来完成一个组件化的示例。

cocoapodsAFNetworking为例。

[cocoapods的Specs索引]-->(AFNetworking的配置信息)-->C(AFNetworking的具体代码)

当我们使用pod search AFNetworking的时候,就是去cocoapodsSpecs索引中找到AFNetworking的配置信息,然后通过这个配置信息,配置信息包含的在github上的代码地址,去获得对应的代码。

现在我们要做的就是按照cocoapods官方的这一套来生成我们自己的一套,我们自己生成一个非官方的Specs索引,在这个索引里只存放公司的库索引,也就是一个个组件,这些组件的具体地址,放到我们想放到的地址下面。如coding私有库,码云,公司部署的gitlab等。

简单的来说就是仿照上图的这三个东西。

准备工作

本地的cocoapods必须要安装好,这里有篇文章写得很好,我就不复述了。文章地址:如何安装cocoapods

详细步骤

  1. 编写组件代码,比如一个轮播图,一个数据库工具等,具体写代码的过程就不说了,这里我使用小码哥的代码来做示范,因为这个实践的文档也是基于一位讲师的文章来做的。

    下面是编写好的代码,在这里分了两个模块,一个是Base,一个是Category。这两个模块不依赖于任何别的第三方文件和库。

  1. 建立自己的Spec索引,这里我们建立在码云上,因为码云免费且没有项目个数的限制。在这里我的Spec项目名为LJDemoSpecs,这里我没有添加ReadMe.gitignore文件。

  2. 现在把第一步中的代码添加到这个pod项目中,添加代码的方法有好几种,这里我仅仅写我使用的方法。

    1. 在对应的Example中编写调试代码,编写完成后如下图所示

    2. 代码已经写完了,也调试好了。现在将对应的代码放到LJDemoBase下的Classes文件夹下,将Classes下已有的Relpace文件删除。

      这里我们直接在finder里操作,不是在Exampleworkspace操作。

  3. 现在如果这就是我们这个小组件的第一个版本,当前代码只是写在本地,需要将他放到远程仓库上。我们在gitoschina建立一个对应的仓库。

    建立好以后如下图所示:

    这里任然不添加ReadMe.gitignore文件,因为pod lib create创建的项目里已经有这两个文件了

  4. 代码虽然已经写完了,但是对应的配置信息却一点都没有写,现在来把配置信息补齐。

    Pod::Spec.new do |s|
    s.name             = "PodTestLibrary"    #名称
    s.version          = "0.1.0"             #版本号
    s.summary          = "Just Testing."     #简短介绍,下面是详细介绍
    s.description      = <<-DESC
                         Testing Private Podspec.
                         * Markdown format.
                        * Don't worry about the indent, we strip it!
                        DESC
    s.homepage         = "https://coding.net/u/wtlucky/p/podTestLibrary"                               #主页,这里要填写可以访问到的地址,不然验证不通过
    # s.screenshots     = "www.example.com/screenshots_1", "www.example.com/screenshots_2"           #截图
    s.license          = 'MIT'              #开源协议
    s.author           = { "wtlucky" => "wtlucky@foxmail.com" }                   #作者信息
    s.source           = { :git => "https://coding.net/wtlucky/podTestLibrary.git", :tag => "0.1.0" }      #项目地址,这里不支持ssh的地址,验证不通过,只支持HTTP和HTTPS,最好使用HTTPS
    # s.social_media_url = 'https://twitter.com/<twitter_username>'                       #多媒体介绍地址
    
    s.platform     = :ios, '7.0'            #支持的平台及版本
    s.requires_arc = true                   #是否使用ARC,如果指定具体文件,则具体的问题使用ARC
    
    s.source_files = 'Pod/Classes/**/*'     #代码源文件地址,**/*表示Classes目录及其子目录下所有文件,如果有多个目录下则用逗号分开,如果需要在项目中分组显示,这里也要做相应的设置
    s.resource_bundles = {
        'PodTestLibrary' => ['Pod/Assets/*.png']
    }                                       #资源文件地址
    
    s.public_header_files = 'Pod/Classes/**/*.h'   #公开头文件地址
    s.frameworks = 'UIKit'                  #所需的framework,多个用逗号隔开
    s.dependency 'AFNetworking', '~> 2.3'   #依赖关系,该项目所依赖的其他库,如果有多个需要填写多个s.dependency
    end
    

    在上面已经将对应的参数通过备注的形式解释了,下面我贴一下我这个组件的podspec的截图,划线部分是修改过的地方。

    现在本地和远程仓库已经关联了

  5. 在我们使用cocoapods的过程中,常常会发现当搜索某个库的时候会有对应的Version,可以使用指定版本的代码来集成到项目中,如下图所示

    -> AFNetworking (3.1.0)
    A delightful iOS and OS X networking framework.
    pod 'AFNetworking', '~> 3.1.0'
    - Homepage: https://github.com/AFNetworking/AFNetworking
    - Source:   https://github.com/AFNetworking/AFNetworking.git
    - Versions: 3.1.0, 3.0.4, 3.0.3, 3.0.2, 3.0.1, 3.0.0, 3.0.0-beta.3, 3.0.0-beta.2, 3.0.0-beta.1, 2.6.3, 2.6.2, 2.6.1,
    2.6.0, 2.5.4, 2.5.3, 2.5.2, 2.5.1, 2.5.0, 2.4.1, 2.4.0, 2.3.1, 2.3.0, 2.2.4, 2.2.3, 2.2.2, 2.2.1, 2.2.0, 2.1.0,
    2.0.3, 2.0.2, 2.0.1, 2.0.0, 2.0.0-RC3, 2.0.0-RC2, 2.0.0-RC1, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0, 1.2.1, 1.2.0, 1.1.0,
    1.0.1, 1.0, 1.0RC3, 1.0RC2, 1.0RC1, 0.10.1, 0.10.0, 0.9.2, 0.9.1, 0.9.0, 0.7.0, 0.5.1 [master repo]
    - Subspecs:
      - AFNetworking/Serialization (3.1.0)
      - AFNetworking/Security (3.1.0)
      - AFNetworking/Reachability (3.1.0)
      - AFNetworking/NSURLSession (3.1.0)
      - AFNetworking/UIKit (3.1.0)
    

    Version对应相关版本的代码,通过git tag的形式来做到区分版本。

    下面我们也给当前的代码制定一下版本,命令非常简单,如下所示就是打了个0.1.0的tag

    liangdeiMac:LJDemoBase apple$ git tag
    liangdeiMac:LJDemoBase apple$ git tag 0.1.0
    liangdeiMac:LJDemoBase apple$ git tag
    0.1.0
    liangdeiMac:LJDemoBase apple$ git push --tags
    Total 0 (delta 0), reused 0 (delta 0)
    To https://git.oschina.net/dev_liang152/ljdemobase.git
    * [new tag]         0.1.0 -> 0.1.0
    

    查看远程仓库,可以看到这就是刚才的tag

  6. 现在提交新的代码,提交代码加打tag都放在下面了

    liangdeiMac:LJDemoBase apple$ git status
    On branch master
    Changes not staged for commit:
    (use "git add <file>..." to update what will be committed)
    (use "git checkout -- <file>..." to discard changes in working directory)
    
        modified:   LJDemoBase.podspec
    
    no changes added to commit (use "git add" and/or "git commit -a")
    liangdeiMac:LJDemoBase apple$ git add .
    liangdeiMac:LJDemoBase apple$ git commit -m"组件内部划分"
    [master 4df9fec] 组件内部划分
    1 file changed, 12 insertions(+), 3 deletions(-)
    liangdeiMac:LJDemoBase apple$ git push
    Counting objects: 3, done.
    Delta compression using up to 4 threads.
    Compressing objects: 100% (3/3), done.
    Writing objects: 100% (3/3), 393 bytes | 0 bytes/s, done.
    Total 3 (delta 2), reused 0 (delta 0)
    To https://git.oschina.net/dev_liang152/ljdemobase.git
       d0dae77..4df9fec  master -> master
    liangdeiMac:LJDemoBase apple$ git tag
    0.1.0
    liangdeiMac:LJDemoBase apple$ git tag 0.2.0
    liangdeiMac:LJDemoBase apple$ git push --tags
    Total 0 (delta 0), reused 0 (delta 0)
    To https://git.oschina.net/dev_liang152/ljdemobase.git
    * [new tag]         0.2.0 -> 0.2.0
    
    
  7. 更新spec索引pod repo push LJDemoSpecs LJDemoBase.podspec

    liangdeiMac:LJDemoBase apple$ pod repo push LJDemoSpecs LJDemoBase.podspec 
    
    Validating spec
    -> LJDemoBase (0.2.0)
        - WARN  | url: The URL (https://git.oschina.net/dev_liang152/ljdemobase) is not reachable.
    
    Updating the `LJDemoSpecs' repo
    
    Already up-to-date.
    
    Adding the spec to the `LJDemoSpecs' repo
    
    - [Update] LJDemoBase (0.2.0)
    
    Pushing the `LJDemoSpecs' repo
    
    To https://git.oschina.net/dev_liang152/ljdemospecs.git
       01c7cdf..f2bb526  master -> master
    
  8. 搜索组件pod search ljdemobase,如下图所示,现在的Versions有0.1.0和0.2.0,且SubspecsBaseCategory了。

    -> LJDemoBase (0.2.0)
       LJDemoBase基础组件
       pod 'LJDemoBase', '~> 0.2.0'
       - Homepage: https://git.oschina.net/dev_liang152/ljdemobase
        - Source:   https://git.oschina.net/dev_liang152/ljdemobase.git
       - Versions: 0.2.0, 0.1.0 [LJDemoSpecs repo]
       - Subspecs:
           - LJDemoBase/Base (0.2.0)
           - LJDemoBase/Category (0.2.0)
    
  9. 现在更新一下项目中使用到的组件,pod update --no-repo-update,至于为什么要加后面的参数是因为不如不加的话会更新pod官方索引,需要的时间比较长,我们不想更新官方的索引。

    liangdeiMac:LJDemoProject apple$ pod update --no-repo-update
    Update all pods
    Analyzing dependencies
    Downloading dependencies
    Installing LJDemoBase 0.2.0 (was 0.1.0)
    Generating Pods project
    Integrating client project
    Sending stats
    Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.
    
  10. 现在再看一下项目中用到的这个组件,发现现在对应的目录结构已经分好了。

  11. 上面的工作都做完以后,现在执行我们的更新组件三部曲

    • 推送组件代码到远程,打tag,这里我直接贴图了,下面的命令在上面的讲解中我已经讲过很多次了

    • 更新spec索引pod repo push LJDemoSpecs LJDemoBase.podspec

      • 子组件依赖第三方

      可以很清晰的看到,子组件如果依赖第三方库,当使用子组件的时候会自动帮我们安装依赖的三方库,而如果没有使用依赖三方库的子组件,并不会安装对应的第三方库

  • 添加依赖的是私有库,比如前面写了个LJDemoBase,现在又要创建一个新的组件叫LJDemoView,它依赖于LJDemoBase

    1. LJDemoViewPodfile中添加对应的私有pod索引,如下图所示

      看清楚,这里是LJDemoViewPodfile

  • 组件直接的相互依赖就说到这里,如果还有问题可以参看下面的官方文档的介绍

    https://guides.cocoapods.org/syntax/podspec.html

    如何更新组件

    1. 添加对应的代码,修改podspec文件,推送到远程

    2. tag并推送tag

    3. 更新spec索引,如pod repo push LJDemoSpecs LJDemoBase.podspec

    4. 使用组件,在项目的Podfile中添加

      我这里只是写的大体步骤,具体步骤上面做了很多次了,相信都已经很了解了

    如何给组件添加资源文件

    在开发组件的过程中,常常需要用到一些资源文件,常见的如图片,xib等。

    这里我就不花大篇幅来讲了,大家可以看这个老师写的添加组件资源的博客

    教你如何从0到1实现组件化架构

    多人协作开发时,如何做到组件化开发

    经过上面的讲解,相信大家应该知道怎么来制作更新一个组件了,但是上面的一切都是基于个人的操作,如何在团队中能够开发并使用是接下来讨论的问题。

    这里我是基于oschina建立了一个组织,组织里就是公司的同事。

    完成后的组织结构如下图所示


    参考资料:

    上一篇 下一篇

    猜你喜欢

    热点阅读