zoukankan      html  css  js  c++  java
  • 基于 svn 服务器及 cocoapods-repo-svn 插件进行组件化私有库的创建

    一、准备

    • 组件化
      • 随着业务需求的增长,在单工程 MVC 模式下,app 代码逐渐变得庞大,面对的高耦合的代码和复杂的功能模块,我们或许就需要进行重构了,以组件化的形式,将需要的组件以 pod 私有库的形式安装到最后的主工程中,组件间各自独立、解耦,仅依赖中间件进行通信,这或许就是极好的架构形式。
    • 使用 CocoaPods
    • 代码文件来源

    二、制作基于 svn 的私有 sepc repo

    • 使用 svn 管理,先在 svn 服务器上新建一个放 spec 的远程仓库,本文以 SpecRepo 命名,该仓库不需要创建标准的 trunk、tags、branches 目录,仅仅是放组件的 spec 文件的。
    • 使用该 SpecRepo svn 地址建立私有 repo,命令行操作如下 pod repo-svn add SpecRepo http://10.211.55.3/svn/SpecRepo
      • 这里是 svn 管理的,利用的是 cocoapods-repo-svn 插件,如果是 git 管理的,那就是默认的 pod repo add xxx git地址

      • 建立了私有 SpecRepo,其本地.cocoapods/repos文件夹目录如下

      • 使用pod repo命令查看 repo 如下

    三、基本的组件化的创建

    • 建立 CRProtocolManager 的组件私有库
      • 使用 svn 管理,先在 svn 服务器上新建一个 CRProtocolManager 的仓库,因为是代码文件且需要使用 tag,所以使用标准的 trunk、tags、branches 目录

      • 使用 pod lib create CRProtocolManager 命令来下载带有默认模板的库,之后基于默认模板进行修改

        • 使用该命令后最回答几个问题,分别是姓名、邮箱(用于 spec 文件中的作者信息)、选择语言(有 Swift 和 ObjC,这里选择 ObjC)、是否需要 demo 工程(这个是需要的,利用这个 demo 进行组件测试)、选择测试库(这里选 None)、do view based testing(这里选 No)
      • 在 Finder 中,将 CRProtocolManager 的核心文件复制到 demo 工程中的 CRProtocolManager 下 Classes 文件夹下,并删除模板文件 ReplaceMe.m

        • 其中 Assets 文件夹下放与该组件有关的图片等资源文件
      • 命令行中 cd Example 工程目录下,pod install 来更新工程的 CRProtocolManager 核心代码

        • 该工程目录下 Podfile 文件中 pod 'CRProtocolManager', :path => '../' ,指向的外层文件夹下的 CRProtocolManager.podspec 文件,因此可以这样添加删除文件后使用pod install 来更新核心代码到工程里
      • 添加完核心代码后,更改 CRProtocolManager.podspec 文件

        • 一个是 s.version 这个和 svn 要打 tag 的编号是一致,例如s.version = '1.0'
        • 一个是 s.source = {:svn =>'http://10.211.55.3/svn/CRProtocolManager', :tag => s.version.to_s },原来 s.source 是 git 地址,这里改为 svn 地址,指向 svn 代码仓库。
        • s.source_files、s.license、s.name(名字和svn仓库名、创建的组件名最好统一)可保持不变
        • s.summary、s.description、s.homepage、s.author 这些描述性的信息按需修改
        • s.ios.deployment_target = '8.0' 按需修改
        # 示例
        Pod::Spec.new do |s|
        s.name             = 'CRProtocolManager'
        s.version          = '1.0'
        s.summary          = 'CRProtocolManager.'
        s.description      = <<-DESC
        CRProtocolManager xxxx
                            DESC
        s.homepage         = 'http://www.baidu.com'
        s.license          = { :type => 'MIT', :file => 'LICENSE' }
        s.author           = { 'HOWIE-CH' => 'zh200742zh@126.com' }
        s.source           = {:svn =>'http://10.211.55.3/svn/CRProtocolManager',  :tag => s.version.to_s }
        s.ios.deployment_target = '8.0'
        s.source_files = 'CRProtocolManager/Classes/**/*' 
        # s.resource_bundles = {
        #   'CRProtocolManager' => ['CRProtocolManager/Assets/*.png']
        # }
        # s.frameworks = 'UIKit', 'MapKit'
        # s.dependency 'AFNetworking', '~> 2.3'
        end
        
      • 将更改好的、测试好的组件提交到 svn CRProtocolManager 仓库 trunk 下,注意:因为模板是从 github.com 上 clone 的,所以这里先把 .git 文件夹删掉。(本文使用的是 smartSVN 管理工具)

      • 对代码进行打 tag,且编号为 1.0,与 spec 文件里的 s.version 一致。

      • 将 CRProtocolManager.podspec 文件提交到之前制作好的私有 sepc repo 中

        • cd 到 CRProtocolManager.podspec 所在目录,使用pod repo-svn push SpecRepo CRProtocolManager.podspec

          • 此时 svn 仓库和 .cocoapods/repo/SpecRepo 下都有 CRProtocolManager.podspec
        • 可在此之前进行 spec 文件有效性检查,pod repo-svn lint CRProtocolManager.podspec

    • 使用 CRProtocolManager 的私有库组件
      • xcode 新建一个工程,使用pod init创建 Podfile 文件
      • Podfile 中默认是搜索 .cocoapods/repo/master 对应的官方默认公用库的源,因此需要 Podfile 中添加本地 repo 源的地址
      platform :ios, '8.0'
          target 'test' do
          plugin 'cocoapods-repo-svn', :sources => [
                  'http://10.211.55.3/svn/SpecRepo' # 添加 svn 服务器中私有库 spec 的 repo
              ] 
          use_frameworks!
          pod 'CRProtocolManager'  # 本地 svn 私有库
          pod 'AFNetworking'    # 可直接 pod 公开第三方库
      end
      
        - git 的话要同时标明私有 repo 地址和默认 repo 地址(以 source 'git地址' 形式)
      
      • 直接使用pod install 即可安装 CRProtocolManager 私有组件
      • 会出现的问题
        • pod install报错找不到组件,可使用pod repo remove SpecRepo后重新添加pod repo-svn add SpecRepo http://10.211.55.3/svn/SpecRepo,然后pod repo-svn update SpecRepo,若还没解决可能是 ruby、CocoaPods 版本不是最新的原因,建议重装后操作。
        • CRProtocolManager.podspec 文件提交到私有 sepc repo中后,pod search CRProtocolManager 搜索不到,可到/Users/HOWIE-CH/Library/Caches/CocoaPods下删除 search_index.json 文件后重试。

    四、私有库和私有库之间的依赖、私有库依赖共有库及 subspec 的应用

    • 其他组件和第三步一样进行操作,最后 svn 服务器截图和 SpecRepo 文件夹截图如下

    • 依赖关系,例如对 CRGoodsDetail 进行探索 svn 的制作私有库之间的依赖的解决

      • CRGoodsDetail 中 CRGoodsDetailServiceProvide 依赖 CRGoodsDetailServiceProtocol 和 CRProtocolManager,CRGoodsDetailViewController 依赖 CRConfirmOrderServiceProtocol 和 CRProtocolManager。
      • pod lib create 创建好工程,进行核心的代码的拷贝和工程的更新操作之后,直接编译会报错的,因为存在依赖关系
      • 在 CRGoodsDetail.podspec 文件中添加
      # 需要的依赖私有库
      s.dependency 'CRProtocolManager'
      s.dependency 'CRConfirmOrderServiceProtocol'
      s.dependency 'CRGoodsDetailServiceProtocol'
      # 依赖公有库 ,可添加依赖的公有库
      s.dependency 'SDWebImage'
      
      • 在工程目录下的 Podfile 文件下添加私有 repo 的 svn 地址,才能下载私有库
      use_frameworks!
      target 'CRGoodsDetail_Example' do
          # 添加私有 repo 的 svn 地址
          plugin 'cocoapods-repo-svn', :sources => [
          'http://10.211.55.3/svn/SpecRepo'
          ]
          pod 'CRGoodsDetail', :path => '../'
      target 'CRGoodsDetail_Tests' do
          inherit! :search_paths
      end
      end
      
      • pod install 就会装好依赖库,包括依赖的私有库和公有库
        • 若出现问题则参考标题三中的解决方案
        • 该 demo 工程 Podfile 文件的 pod 'CRGoodsDetail' 指向上一个目录的 CRGoodsDetail.podspec 文件,因此会检测 s.dependency 依赖的库,依赖的私有库是在从 Podfile 中添加的私有 repo 的 svn 地址中去找的
      • 该 demo 工程运行测试后没有报错后,要提交 svn,打(新) tag(组件的迭代开发维护),提交 spec 文件到私有 repo 中
    • subspec 的使用

      • 例如 CRGoodsDetail 中可分为模块文件(MVC 文件)及 Provider 文件,因此可使用 subspec

      • CRGoodsDetail 核心代码中分文件夹

      • CRGoodsDetail.podspec 文件中

      # subspec 及各自的依赖私有库
      s.subspec 'Module' do |m|
          m.source_files = 'CRGoodsDetail/Classes/Module/*'
          # 依赖私有库
          m.dependency 'CRConfirmOrderServiceProtocol'
          # 依赖公有库
          m.dependency 'SDWebImage'
      end
      s.subspec 'Provider' do |p|
          p.source_files = 'CRGoodsDetail/Classes/Provider/*'
          p.dependency 'CRGoodsDetailServiceProtocol'
      end
      # 公用的依赖私有库
      s.dependency 'CRProtocolManager'
      
      • 使用 subspec 后 pod search 效果

      • Podfile 中使用 subspec

      # pod 'CRGoodsDetail', :subspecs =>['Module'] #只加载本地 svn 私有库的某个 subspec
      pod 'CRGoodsDetail'   # 完整的 svn 私有库
      

    五、图片资源、xib文件等

    • 创建的 demo 工程中,组件相关的图片是放到 Assets 文件下
    • spec 文件中需要添加
      s.resource_bundles = { 'CRGoodsDetail' => ['CRGoodsDetail/Assets/*'] }
    • 组件代码中加载图片不在是直接 imageName 了,图片打包的是一个 bundle 且 整个组件并不在 mainbundle 中,而是先要找到组件对应的 framework 包(可查看 Products 下,编译的 app 里的结构),然后找图片路径进行加载
    • 组件中的 xib
      • 使用 xib,以前的工程,xib 在 mainbundle 中。以组件形式的话,xib 在组件对应的 framework 包中
      • xib 中的图片路径,跟上面一样需要添加图片资源包的相对路径

    六、其他

    • 使用 svn 的话,会提示输入用户名、密码,有时会因此报错,建议一开始就直接命令行 svn checkout xxx 一次,让电脑记住用户名、密码
    • 重构是一个细心的工作,尤其是组件的抽取、剥离,一般会分业务层、基础层、功能层等,业务层里有各个的业务功能模块,基础层里有常量、宏、工具类、分类等,功能层里是能够抽取出来的某些具体功能方法,相同层内的不同组件不产生依赖,业务层会依赖基础层和功能层,基础层和功能层之间不依赖,实际工作中还需要具体情况具体对待
    • 最后的主工程,需导入各个业务层里的组件,这里组件间的通信又是讨论的话题,url 、protocol、Target-Action等方案,自己也在学习和实践阶段,就不讨论,本文仅记录一些过程和问题。
  • 相关阅读:
    122. Best Time to Buy and Sell Stock II
    121. Best Time to Buy and Sell Stock
    72. Edit Distance
    583. Delete Operation for Two Strings
    582. Kill Process
    indexDB基本用法
    浏览器的渲染原理
    js实现txt/excel文件下载
    git 常用命令
    nginx进入 配置目录时
  • 原文地址:https://www.cnblogs.com/howie-ch/p/7140678.html
Copyright © 2011-2022 走看看