一.創(chuàng)建一個工程xxx
- 把需要開源的文件放到這個工程對應文件夾里,保證運行成功。(文件夾也會顯示到開源庫的目錄結構),比如
Category文件夾,對應NSURLSession
WX20210903-143040.png
WX20210903-143134.png
二.github創(chuàng)建一個倉庫,并把工程xxx與這個倉庫綁定(github實在太慢,用coding創(chuàng)建倉庫替代了)
- 上傳代碼到倉庫后,記得打tag:
(cocoapods的版本記錄就是這個tag)git tag 1.0.0 git push --tags - 碼云coding倉庫的創(chuàng)建與本地工程綁定
三. 安裝CocoaPods
- 沒有安裝cocoapods,m1芯片安裝cocoapods
- 更新cocoapods版本:
pod --version //查看版本 sudo gen install cocoapods pod setup //低于0.33,需要更新
四.配置.podspec文件
-
注冊:
(已經(jīng)注冊的先忽略)pod trunk me -
創(chuàng)建.podspec:
pod spec create xxx //xxx為開源庫的名稱 -
編輯.podspec: Cocoapods官方命令文檔(可能需要翻墻)
-
開源的一些編輯:
Pod::Spec.new do |spec| spec.name = "xxx" //開源庫名 spec.version = "1.0.0" //開源版本號,對應倉庫的tag spec.summary = "iOS開發(fā)組件化" // 簡介 spec.description = <<-DESC 一些開發(fā)組件化 //描述 (DESC不能刪掉) DESC spec.homepage = "https://e.coding.net/xxx.git" //開源庫的倉庫地址 # spec.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif" -
開源協(xié)議的編輯:
(coding碼云沒有l(wèi)icense,可以到github下載一個放到倉庫)spec.license = { :type => "MIT", :file => "LICENSE" } -
作者信息的編輯:
#spec.author = { "tucici" => "00000@qq.com" } spec.author = "tucici" // 二選一 -
開源庫發(fā)布的平臺的編輯:
spec.platform = :iOS //這里設置只發(fā)布iOS平臺 # spec.platform = :ios, "5.0" # When using multiple platforms # spec.ios.deployment_target = "5.0" # spec.osx.deployment_target = "10.7" # spec.watchos.deployment_target = "2.0" # spec.tvos.deployment_target = "9.0" -
開源庫的資源編輯:
spec.source = { :git => "#{spec.homepage}", :tag => "#{spec.version}" }-
其他常見的寫法:
spec.source = { :git => "https://github.com/xxx/xxx.git", :commit => "98emfox" } spec.source = { :git => "https://github.com/xxx/xxx.git", :tag => 1.0.0 } spec.source = { :git => "hhttps://github.com/xxx/xxx.git", :tag => spec.version }-
commit => "98emfox"表示pod版本與git倉庫指定的commit= 98emfox綁定 -
tag => 1.0.0表示pod版本與git倉庫指定的tag=1.0.0綁定 -
tag => spec.version表示pod版本與倉庫的tag保持一致。spec.version就是.podspec最開始編輯參數(shù)spec.version = "1.0.0"
-
-
-
開源庫需要包含的源文件:
spec.source_files = "CCKit", "CCKit/Category/*.{h,m}" spec.exclude_files = "Classes/Exclude" # spec.public_header_files = "Classes/**/*.h" //需要包含的頭文件CCKit文件夾是與.podspec同一級,上面配置的結果是,開源庫會包含CCKit/Category/里面所有的.h.m文件 -
開源庫依賴靜態(tài)庫/動態(tài)庫的編輯:
spec.frameworks = "Foundation", "UIKit" //這里就只依賴官方庫 -
依賴第三方開源庫的編輯:
spec.dependency "AFNetworking", "~> 1.0.0" -
大體上配置就這樣,其實看.podspec的注釋,可以大概明白每個配置是干嘛的
-
五.驗證.podspec
pod spec lint xxx.podspec --verbose
-
驗證成功提示:
xxx.podspec passed validation.
六.成功發(fā)布
-
發(fā)布:
pod trunk push xxx.podspec -
成功:
Updating spec repo `trunk` -------------------------------------------------------------------- ------------ ?? Congrats ?? xxx (1.0.0) successfully published ?? September 3rd, 04:29 ?? https://cocoapods.org/pods/xxxx ?? Tell your friends! -
搜索發(fā)布的開源庫xxx:
rm ~/Library/Caches/CocoaPods/search_index.jsonpod repo update過幾分鐘后,搜索,就能成功顯示,有時候可能需要等更久:pod search XXX -
刪除已發(fā)布的版本:
pod trunk delete ZHPageView 1.0.0
七.錯誤及解決:
-
Specs satisfying the `xxxx (~> 1.0.0)` dependency were found, but they required a higher minimum deployment target.:
解決:三方依賴庫xxxx設置里支持最低的ios版本,所以本開源庫設置ios版本要高于xxxx支持的ios版本 -
Encountered an unknown error (/usr/bin/xcrun simctl list -j devices:
解決: Xcode->Preferences->Locations->Command line tools,選擇一個Xcode版本 -
[!] The spec did not pass validation, due to 3 warnings (but you can use `--allow-warnings` to ignore them).:
解決:pod spec lint xxx.podspec --verbose --allow-warnings
八.注意:
- 每次更新完庫文件,同時也要更新遠程倉庫的tag,在驗證
pod spec lint xxx.podspec --verbose的時候,要先把本地tag刪掉,否則會報錯xxxx...HEAD...xxxx錯誤 - cocoapods本地有對應緩存,有時候即使已經(jīng)改的可以發(fā)布了,由于設置的版本
spec.version = "1.0.0",在本地已經(jīng)有緩存了,驗證發(fā)布的時候還是會報錯,需要清理下本地緩存:pod cache list,找到相應文件路徑,清理。
九.tag相關命令行:tag的相關命令
十.OC與Swift混編,有子文件夾的開源庫
- OC與Swift混編到pods開源庫:
- 一個開源庫里不僅有OC類,還有Swif類。
- 并且在這個開源庫里, Swift與OC還會互相調(diào)用。
- 并且Swift和OC還混合存在于不同的文件夾。
-
并且要求發(fā)布的開源庫在pods里不是一股腦在一個文件夾顯示所有文件,而是跟在project中一樣,也就是說,如圖:
112212121.png
-
- 解決:
- Swift調(diào)用OC好說,跟平常app開發(fā)一樣,在橋接文件里導入OC的頭文件
- OC調(diào)用Swift
- oc文件引用 :
#if FMWK #import <XXXKit/XXXKit-Swift.h> #else #import "XXXKit_Swift.h"http:///這文件是復制XXXKit-Swift.h的內(nèi)容 #endif- swift 類文件:
@objc public class NotifyTool:NSObject { @objc public class func add(_ observer:Any){} }- swift 擴展分類文件:
@objc public extension NSString{ func color(_ alpha : Float) -> UIColor{ return (self as String).color(alpha)} func color() -> UIColor{return (self as String).color()} }
- 問題1:
會報某個文件夾的OC文件里找不到Swift方法的錯誤, 原因是找不到XXXKit-Swift.h里的對應的方法-
XXXKit_Swift.h這個文件是XXXKit-Swift.h的拷貝。因為app開發(fā)用到XXXKit-Swift.h就可以了。但是開源庫不同文件夾里的OC調(diào)用不同文件夾的Swift方法,相當于不同project的OC調(diào)用不同project的Swift方法。那么在開發(fā)開源庫的project里生成的XXXKit-Swift.h,就包含了所有不同文件夾的Swift方法,我們所需要的就是新建一個.h文件,拷貝XXXKit-Swift.h的內(nèi)容,哪個文件夾的OC需要調(diào)用Swift,就把這個.h保存一遍。在開發(fā)開源庫的p roject的Run Script添加腳本如下:
-
generated_header_file=${DERIVED_SOURCES_DIR}/*-Swift.h
# include_dir=${BUILT_PRODUCTS_DIR}/include/${PRODUCT_MODULE_NAME}/
include_dir=${BUILT_PRODUCTS_DIR}/include/${PRODUCT_MODULE_NAME}/
# 將編譯器生成的 xxx-Swift 頭文件拷貝到 build 目錄下的 include 目錄中
#mkdir -p ${include_dir}
#cp ${generated_header_file} ${include_dir}
# 去掉 xxx-Swift.h 文件頭部注釋中的編譯器的版本號
sed -i "" "s/^\/\/ Generated by Apple.*$/\/\/ Generated by Apple/g" ${generated_header_file}
# 拷貝 xxx-Swift.h 文件到工程源碼目錄
header_file_in_proj=${SRCROOT}/${PROJECT}-Swift.h
needs_copy=true
if [ -f "$header_file_in_proj" ]; then
echo "${header_file_in_proj} 已存在"
new_content=$(cat ${generated_header_file})
old_content=$(cat ${header_file_in_proj})
if [ "$new_content" = "$old_content" ];then
echo "文件內(nèi)容一致,無需再Copy:"
echo "${generated_header_file} "
echo "${header_file_in_proj} "
needs_copy=false
fi
fi
if [ "$needs_copy" = true ] ; then
echo "文件內(nèi)容不一致,需要Copy:"
echo "復制文件: "
echo "${generated_header_file} "
echo "${header_file_in_proj} "
cp ${generated_header_file} ${header_file_in_proj}
fi
# 拷貝 xxx-Swift.h 文件到開源庫根目錄得 /Extension文件夾下
header_file_in_path=${SRCROOT}/${PROJECT_NAME}/${PROJECT_NAME}/Extension/${PROJECT}_Swift.h
needs_copy_path=true
if [ -f "$header_file_in_path" ]; then
echo "${header_file_in_path} 已存在"
new_content=$(cat ${generated_header_file})
old_content=$(cat ${header_file_in_path})
if [ "$new_content" = "$old_content" ];then
echo "文件內(nèi)容一致,無需再Copy:"
echo "${generated_header_file} "
echo "${header_file_in_path} "
needs_copy_path=false
fi
fi
if [ "$needs_copy_path" = true ] ; then
echo "文件內(nèi)容不一致,需要Copy:"
echo "復制文件: "
echo "${generated_header_file} "
echo "${header_file_in_path} "
cp ${generated_header_file} ${header_file_in_path}
fi
- 問題2:
會報某個文件夾的Swift文件里找不到OC方法的錯誤, 原因是Swift文件夾里找不到橋接文件.h,如果可以,也把橋接文件一樣拷貝到Swift存在的文件夾里。 - 問題3: 生成帶子文件夾的.podspec配置
spec.source_files = "XXX/header/*.{h,m,swift,strings}"http:///總的開源庫,
# spec.exclude_files = "Classes/Exclude"
spec.public_header_files = "XXX/header/*.h"
#spec.prefix_header_file = "XXX/header/PrefixHeader.pch"
///依賴的本地子開源庫(project)的一個文件夾,這個庫在開發(fā)project的文件夾名 = ```header ```
spec.subspec 'XXX' do |ss|
ss.source_files = 'XXX/header/**/*.{h,m,swift,strings}
end
///依賴的本地子開源庫(project)的一個文件夾,這個庫在開發(fā)project的文件夾名 = ```header ```
spec.subspec 'CCTool' do |ss|
ss.source_files = 'XXX/CCTool/*.{h,m,swift,strings}'
ss.dependency 'XXX/CCTool'DSSss.dependency 'TCCKit/公用組件'
ss.dependency 'TCCKit/Extension'
end
- 一切正常的話,就會發(fā)布個XXX開源庫,XXX下面有兩個文件夾
heade和CCTool -
總結:所有找不到文件,都是某個地方?jīng)]設置好。一個一個檢查,總能解決問題。
- 一個開源庫的總文件下的各個子文件夾,其實就相當于根文件夾下面依賴了不同的庫,只不過這些庫么有發(fā)布到cocoapods,是一起的,因此要設置好.podspec文件依賴關系
(重復問題3的辦法),要避免循環(huán)依賴。
- 一個開源庫的總文件下的各個子文件夾,其實就相當于根文件夾下面依賴了不同的庫,只不過這些庫么有發(fā)布到cocoapods,是一起的,因此要設置好.podspec文件依賴關系
- 2.在驗證庫時候,可能會一直出現(xiàn)找不到響應的方法/類等錯誤,這個就是不同文件夾的OC/Swift互相調(diào)用的問題了,說白了,就是
XXX-Swift.h和橋接文件沒引用好。在同一個工程,我們可以直接把XXX-Swift.h和橋接文件,導入到PrefixHeader.pch,就可以了。(重復問題1/問題2的辦法)


