基於 svn 服務器及 cocoapods-repo-svn 插件進行組件化私有庫的建立

1、準備

  • 組件化
    • 隨着業務需求的增加,在單工程 MVC 模式下,app 代碼逐漸變得龐大,面對的高耦合的代碼和複雜的功能模塊,咱們或許就須要進行重構了,以組件化的形式,將須要的組件以 pod 私有庫的形式安裝到最後的主工程中,組件間各自獨立、解耦,僅依賴中間件進行通訊,這或許就是極好的架構形式。
  • 使用 CocoaPods
    • 若是你的 Mac 系統升級過了,避免出現莫名的問題,強烈建議重裝 CocoaPods 及更新 ruby。(可參考 http://www.jianshu.com/p/8169f5d7f364)
    • CocoaPods 下載框架的原理及 spec、Podfile 文件,可參考 http://www.jianshu.com/p/8a7b9232cbab 或 http://blog.csdn.net/morenyaojing/article/details/53376475 。
    • CocoaPods 默認的 spec repo,是基於 git 的,可建立基於 git 管理的私有庫 spec repo,因公司性質及要求,代碼一概使用內部 svn 管理。所以本文徹底使用 svn,來進行私有庫製做。(使用 git 的文章網上不少,更方便,其實最終感受也都差很少)
    • 安裝 cocoapods-repo-svn 插件,參考 https://github.com/dustywusty/cocoapods-repo-svn 。
  • 代碼文件來源
    • 因公司項目緣由,本文以網上的 demo 代碼來演示。demo 來源 https://github.com/sun6boys/CRMainProject

2、製做基於 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文件夾目錄以下
      ios

    • 使用pod repo命令查看 repo 以下
      git

3、基本的組件化的建立

  • 創建 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 文件後重試。

4、私有庫和私有庫之間的依賴、私有庫依賴共有庫及 subspec 的應用

  • 其餘組件和第三步同樣進行操做,最後 svn 服務器截圖和 SpecRepo 文件夾截圖以下

    github

  • 依賴關係,例如對 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 核心代碼中分文件夾
      json

    • 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 效果
      xcode

    • Podfile 中使用 subspec
    # pod 'CRGoodsDetail', :subspecs =>['Module'] #只加載本地 svn 私有庫的某個 subspec
    pod 'CRGoodsDetail'   # 完整的 svn 私有庫

5、圖片資源、xib文件等

  • 建立的 demo 工程中,組件相關的圖片是放到 Assets 文件下
  • spec 文件中須要添加
    s.resource_bundles = { 'CRGoodsDetail' => ['CRGoodsDetail/Assets/*'] }
  • 組件代碼中加載圖片不在是直接 imageName 了,圖片打包的是一個 bundle 且 整個組件並不在 mainbundle 中,而是先要找到組件對應的 framework 包(可查看 Products 下,編譯的 app 裏的結構),而後找圖片路徑進行加載
  • 組件中的 xib
    • 使用 xib,之前的工程,xib 在 mainbundle 中。以組件形式的話,xib 在組件對應的 framework 包中
    • xib 中的圖片路徑,跟上面同樣須要添加圖片資源包的相對路徑

6、其餘

  • 使用 svn 的話,會提示輸入用戶名、密碼,有時會所以報錯,建議一開始就直接命令行 svn checkout xxx 一次,讓電腦記住用戶名、密碼
  • 重構是一個細心的工做,尤爲是組件的抽取、剝離,通常會分業務層、基礎層、功能層等,業務層裏有各個的業務功能模塊,基礎層裏有常量、宏、工具類、分類等,功能層裏是可以抽取出來的某些具體功能方法,相同層內的不一樣組件不產生依賴,業務層會依賴基礎層和功能層,基礎層和功能層之間不依賴,實際工做中還須要具體狀況具體對待
  • 最後的主工程,需導入各個業務層裏的組件,這裏組件間的通訊又是討論的話題,url 、protocol、Target-Action等方案,本身也在學習和實踐階段,就不討論,本文僅記錄一些過程和問題。
相關文章
相關標籤/搜索