私有庫的使用場景
場景一、在iOS開發的過程中,我們會因開發需要而使用Cocoapods引入各種三方庫,但有時為了更切合項目需求,不得不去修改三方庫的源碼。一旦pod update升級了三方庫,原來修改的代碼就沖掉了,這就不得不使用git回滾修改的區塊或者再改一遍,這就造成升級困難。尤其是在團隊里開發的過程中,如果其它隊員不知道你改了三方源碼,這一升級直接導致你的修改代碼丟失而出現bug。
場景二、有一些成熟的三方庫,不支持pods導入,這個比較少見。
場景三、項目里成熟的功能模塊可以從項目里剝離,通過pods導入。
對于這幾種場景,我們可以通過以下幾個方法來解決,下面來詳細介紹下:
一、pods導入本地庫
1.創建Podfile
touch Podfile 或 vim Podfile(可直接編輯)
2.創建MyTestKit文件夾,并創建podspec文件
pod spec create MyTestKit
文件目錄結構如下:
3.把需要pods引入的文件放到MyTestKit目錄下
4.修改podspec文件
這是最重要的一步,需要了解podspec文件的寫法,各種字段的涵義。可刪除不必要的注釋(更多字段請參考http://guides.cocoapods.org/syntax/podspec.html)
修改后的podspec文件
#
#? Be sure to run `pod spec lint MyTestKit.podspec' to ensure this is a
#? valid spec and to remove all comments including this before submitting the spec.
#
#? To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
#? To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
#
Pod::Spec.new do |s|
# ―――? Spec Metadata? ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
#? These will help people to find your library, and whilst it
#? can feel like a chore to fill in it's definitely to your advantage. The
#? summary should be tweet-length, and the description more in depth.
#
s.name? ? ? ? = "MyTestKit"
s.version? ? ? = "0.0.1"
s.summary? ? ? = "MyTestKit demo."
# 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? = "description"
s.homepage? ? = "https://github.com/zhfeng20108"
# s.screenshots? = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
# ―――? Spec License? ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
#? Licensing your code is important. See http://choosealicense.com for more info.
#? CocoaPods will detect a license file if there is a named LICENSE*
#? Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
#
s.license? ? ? = "MIT"
# s.license? ? ? = { :type => "MIT", :file => "FILE_LICENSE" }
# ――― Author Metadata? ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
#? Specify the authors of the library, with email addresses. Email addresses
#? of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
#? accepts just a name if you'd rather not provide an email address.
#
#? Specify a social_media_url where others can refer to, for example a twitter
#? profile URL.
#
s.author? ? ? ? ? ? = { "feng.zhang" => "hhzhangfeng2008@163.com" }
# Or just: s.author? ? = "feng.zhang"
# s.authors? ? ? ? ? ? = { "feng.zhang" => "hhzhangfeng2008@163.com" }
# s.social_media_url? = "http://twitter.com/feng.zhang"
# ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
#? If this Pod runs only on iOS or OS X, then specify the platform and
#? the deployment target. You can optionally include the target after the platform.
#
# s.platform? ? = :ios
s.platform? ? = :ios, "8.0"
#? When using multiple platforms
# s.ios.deployment_target = "5.0"
# s.osx.deployment_target = "10.7"
# s.watchos.deployment_target = "2.0"
# s.tvos.deployment_target = "9.0"
# ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
#? Specify the location from where the source should be retrieved.
#? Supports git, hg, bzr, svn and HTTP.
#
s.source? ? ? = { :git => "", :tag => "#{s.version}" }
# ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
#? CocoaPods is smart about how it includes source code. For source files
#? giving a folder will include any swift, h, m, mm, c & cpp files.
#? For header files it will include any header in the folder.
#? Not including the public_header_files will make all headers public.
#
# s.source_files? = "Classes", "Classes/**/*.{h,m}"
# s.exclude_files = "Classes/Exclude"
# s.public_header_files = "Classes/**/*.h"
# ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
#? A list of resources included with the Pod. These are copied into the
#? target bundle with a build phase script. Anything else will be cleaned.
#? You can preserve files from being cleaned, please don't preserve
#? non-essential files like tests, examples and documentation.
#
# s.resource? = "icon.png"
# s.resources = "Resources/*.png"
# s.preserve_paths = "FilesToSave", "MoreFilesToSave"
# ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
#? Link your library with frameworks, or libraries. Libraries do not include
#? the lib prefix of their name.
#
s.vendored_frameworks = 'HeheTest.framework'
# s.framework? = "SomeFramework"
# s.frameworks = "SomeFramework", "AnotherFramework"
s.vendored_libraries = 'libHeheTestStatic.a'
# s.library? = "iconv"
# s.libraries = "iconv", "xml2"
# ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
#? If your library depends on compiler flags you can set them in the xcconfig hash
#? where they will only apply to your library. If you depend on other Podspecs
#? you can include multiple dependencies to ensure it works.
s.requires_arc = true
# s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
# s.dependency "JSONKit", "~> 1.4"
s.subspec "HeaderFiles" do |ss|
ss.public_header_files = "include/**/*.h"
ss.source_files = "include/**/*.h"
ss.requires_arc = true
end
end
5.執行pod install命令
按照提示把podspec文件修改正確,直到pod install執行成功
最后工程結構如下圖所示:
二、pods導入網絡上的庫并解決沖突問題
1.導入GitHub上的三方庫
這個是我們用的最多的情況,不再贅述。
2.導入私有倉庫里的庫
隨著項目開發的迭代,工程越來越大,很有必要把一些自定義控件、功能模塊從工程里剝離出來,移植給更多的項目使用。要導入庫,需要具備兩個條件:(1)源碼倉庫(2)對應的podspec.json文件的倉庫
對于源碼倉庫和podspec.json文件的倉庫,可以是github上的,也可以是自己公司的私有倉庫。解決多個三方庫沖突的方法就是在這里做文章。咱們就先來講講如何導入私有庫。如下是一個示例:
platform :ios, '8.0'
source 'https://github.com/zhfeng20108/podsecRepo.git'
source 'https://github.com/CocoaPods/Specs.git'
target 'TestDemo' do
pod 'MyTestKit', :path => 'MyTestKit'
pod 'gRPC-Core'
end
可以看出 gRPC-Core 下載的版本是1.3.0, 而GitHub 上的最新版本是1.6.0
從中可以看出,會優先在'https://github.com/zhfeng20108/podsecRepo.git'里查找podspec.json文件。這樣我們就可以對gRpc-Core.podspec.json文件做任何更改,上面的例子中,是對依賴做了修改,由BoringSSL改成了OpenSSL。這里的修改是為了避免BoringSSL和OpenSSL同時引入pods造成方法重命名的沖突。
3.沖突解決
(1)上面這個案例只是修改了dependencies字段的值,當然了我們可以根據需要去修改platforms,source,source_files,vendored_frameworks,vendored_libraries等等字段的值來避免與其它三方庫的沖突。
(2)碰上源代碼方法名重名的情況,這時就需要修改三方的源代碼。
方案一:把修改好的源代碼存到一個新的倉庫里,比如公司的一個倉庫里,同時把修改好的podspec文件(這時主要修改的是source字段里的值,git地址指向公司的倉庫)存在公司的另一個倉庫里。
方案二:fork源代碼到自己的github帳號下,然后修改代碼,引入時采用 pod 'RSKImageCropper',:git => 'https://github.com/zhfeng20108/RSKImageCropper',即可指向修改后的代碼庫。復雜的可能就需要在自己帳號下再建一個庫存放podspec.json文件,以便精確控制代碼。
以上兩種方案,無論哪種,都會遇上三方源碼升級問題,對于方案一,我們只能把最新代碼copy過去,檢查下原來修改的代碼現在是否需要調整。對于方案二,可通過方法fork后代碼和源代碼同步來解決。