接著上篇文章"Swift/Objective-C-使用Cocoapods創(chuàng)建/管理私有庫(初中級用法)"的探索之路。
另外兩篇文章:
Swift/Objective-C-使用Cocoapods創(chuàng)建/管理公共庫
Swift/Objective-C-使用Cocoapods創(chuàng)建/管理私有庫(初中級用法)
- 高級
- 通過subspec創(chuàng)建子模塊(pod時可根據(jù)需要引入私有庫的某個或者某幾個模塊到項目中拳氢,用不到的模塊不引入);
- 私有庫中ARC和MRC文件的配置哼拔;
- 依賴自己其他的私有庫到當(dāng)前創(chuàng)建的私有庫中概行;
- 添加第三方公共庫到私有庫中(兩種情況:含/不含動態(tài)(.framework)、靜態(tài)(.a)文件)儒鹿;
- 私有庫中Swift和Objective-C混編化撕;
一、通過subspec創(chuàng)建子模塊约炎,及子模塊之間的引用
Subspecs是一種分解Podspec功能的方法植阴,它允許人們安裝庫的一個子集。也就是說圾浅,一個私有庫中掠手,包含很多模塊,有時我們只需要pod這個私有庫中的某個或者某些模塊狸捕,選擇性的使用喷鸽,并不是pod全部,這時我們就需要在私有庫中添加subspec灸拍,將各個模塊開放分解出來做祝,成為一個單獨的子模塊,以實現(xiàn)這樣的需求鸡岗』旎保或者私有庫中的某個模塊和某個模塊之間有引用關(guān)聯(lián),為了不影響其他模塊的使用和冗余轩性,也需要將這部分和其他模塊區(qū)分開声登,也需要添加subspec。
在添加subspec時需要我們在編碼的過程中盡量減少模塊之間的依賴揣苏,使各個模塊兒可以獨立運行悯嗓。
- .podspec文件中添加子模塊(subspec),并設(shè)置子模塊鍵舒岸,配置如下:
Pod::Spec.new do |s|
s.name = 'JYPrivateLibTest0'
s.version = '1.0.1'
s.summary = '這是一個私有測試庫绅作!'
s.homepage = 'https://git.asd.net/pod/JYPrivateLibTest0'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'JYanshao' => '654565181@qq.com' }
s.source = { :git => 'https://git.asd.net/pod/JYPrivateLibTest0.git', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
s.requires_arc = true
s.swift_version = '4.0'
# s.source_files = 'JYPrivateLibTest0/Classes/**/*'
# ------ 創(chuàng)建子模塊 ------
s.subspec 'TextField' do |tf| # tf為子模塊鍵
tf.source_files = 'JYPrivateLibTest0/Classes/TextField/*'
tf.dependency 'JYPrivateLibTest0/Constant' # TextField模塊中文件使用了Constant模塊的東西,所以需要引入依賴蛾派。如果不寫依賴俄认,當(dāng)你只引入TextField模塊的時候,就會報錯洪乍,由于找不到Constant模塊中你使用的東西眯杏。這里不可以直接引入主spec,即tf.dependency 'JYPrivateLibTest0'壳澳,因為cocospods不允許(podspec文件:[!子規(guī)范不能要求它的父規(guī)范岂贩。),且在實際項目中引入時引入不成功巷波,錯誤移步下邊萎津。
end
s.subspec 'Constant' do |c| # c為子模塊鍵
c.source_files = 'JYPrivateLibTest0/Classes/Constant/*'
end
end
在上面的例子中卸伞,一個工程中,有多個模塊锉屈,并把各模塊分解為子模塊荤傲,使用 pod 'JYPrivateLibTest0'
的Podfile會包含整個庫,而 pod 'JYPrivateLibTest0/Constant'
會只包含Constant模塊颈渊。只引入你的項目中需要的模塊遂黍,其他不需要的可以不引入。
- 問題:
tf.dependency 'JYPrivateLibTest0/Constant'
TextField模塊中文件使用了Contants模塊的東西俊嗽,子模塊的依賴不能直接依賴父spec雾家,如tf.dependency 'JYPrivateLibTest0'
, 這樣cocospods是不允許,你pod的時候也不會pod成功绍豁,錯誤如下:
Analyzing dependencies
Fetching podspec for `JYPrivateLibTest0 ` from `../`
[!] Failed to load 'JYPrivateLibTest0' podspec:
[!] Invalid `JYPrivateLibTest0.podspec` file: [!] A subspec can't require one of its parents specifications.
# from /Users/123456/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0.podspec:49
# -------------------------------------------
# tf.source_files = 'JYPrivateLibTest0/Classes/TextField/*'
> tf.dependency 'JYPrivateLibTest0'
# end
# -------------------------------------------
解釋:[!]加載“ JYPrivateLibTest0”podspec失敗:
[! JYPrivateLibTest0]無效”芯咧。podspec文件:[!子規(guī)范不能要求它的父規(guī)范。
也就是說:同一工程中一子模塊使用了另一子模塊的東西妹田,需要引入對另一子模塊的依賴唬党,且另一子模塊也必須為subspec,不能直接依賴父spec鬼佣。
二驶拱、私有庫中ARC(自動內(nèi)存管理)和MRC(手動內(nèi)存管理)文件的配置
我這里找到一個使用Objective-C寫的Base64加密的封裝(Base64.h/Base64.m),且為MRC(手動內(nèi)存管理)晶衷。下面讓我們看一下如何來區(qū)別對待MRC和ARC文件吧蓝纲,即如何讓Cocoapods自動給MRC的文件添加-fno-objc-arc
標(biāo)識,使MRC和ARC共存晌纫。
- 方法一:在.podspec文件中税迷,先將整個子模塊設(shè)置為MRC,即
ocb.requires_arc = false
锹漱,再通過requires_arc
設(shè)置ARC文件箭养,具體如下:(官方推薦)
Pod::Spec.new do |s|
...
// 此處省略一些不便的配置
...
s.subspec 'OCBase64' do |ocb|
ocb.requires_arc = false
ocb.requires_arc = ['JYPrivateLibTest0/Classes/OCBase64/*.{h,m}']
end
end
- 方法二:在.podspec文件中,先將子整個模塊設(shè)置為ARC哥牍,即
ocb.requires_arc = true
毕泌,然后再通過exclude_files
、subspec
設(shè)置MRC文件嗅辣,具體如下:
Pod::Spec.new do |s|
...
// 此處省略一些不便的配置
...
s.subspec 'OCBase64' do |ocb|
ocb.requires_arc = true # 如果其他地方已經(jīng)寫了這句撼泛,可省略;或者直接省略也可
ocb.source_files = 'JYPrivateLibTest0/Classes/OCBase64/*'
non_arc_files = 'JYPrivateLibTest0/Classes/OCBase64/Base64/*.{h,m}'
ocb.exclude_files = non_arc_files # 排除MRC文件
ocb.subspec 'no-arc' do |dd|
dd.source_files = non_arc_files
dd.requires_arc = false
end
end
end
這兩種配置方法的區(qū)別就是:
方法一澡谭,在項目中拉取私有庫的時候愿题,不會自動創(chuàng)建一個包含MRC文件的文件夾,看起來代碼比較整齊。
方法二潘酗,在項目中拉取私有庫的時候杆兵,會自動創(chuàng)建一個包含MRC文件的文件夾。
三仔夺、私有庫中依賴其他私有庫
-
私有庫中依賴其他的私有庫
這里以TESTRely私有庫為例拧咳,該私有庫中除了自己的封裝還依賴了公共庫AFNetworking。
將自己使用了TESTRely私有庫的源代碼封裝文件囚灼,添加到Classes文件夾目錄下,步驟參考上邊的步驟祭衩;
配置.podspec文件灶体,參數(shù)如下:(這里都是以子模塊的形式添加的)
Pod::Spec.new do |s|
...
// 這里省略沒改變的配置
...
s.subspec 'TestController' do |tc|
tc.source_files = 'JYPrivateLibTest0/Classes/TestController/*'
tc.dependency 'TESTRely', '~>0.0.6' # 依賴TESTRely私有庫
end
end
- 配置demo工程的Podfile文件,通過
source
添加TESTRely私有庫對應(yīng)的索引庫地址和TESTRely依賴的公共庫AFNetworking對應(yīng)的索引庫地址掐暮,如下:
source 'https://git.asd.net/pod/JYPrivateRepoTest0.git' # JYPrivateRepoTest0對應(yīng)的私有索引庫地址
source 'https://git.asd.net/CocoaPods/TESTRelyLibrary.git' # TESTRely對應(yīng)的私有索引庫地址
source 'https://github.com/CocoaPods/Specs.git' # 官方公共庫對應(yīng)的公共索引庫地址
注意:
在項目中使用私有庫蝎抽,這個私有庫又中的封裝又依賴其他私有庫或公共庫,則項目的Podfile文件中路克,需要將該私有庫樟结,以及其依賴的其他私有庫或公共庫的索引庫地址都添加到Podfile文件中,否則會報錯精算,找不到依賴的其他私有庫或公共庫瓢宦。
pod install
時錯誤如下:
Analyzing dependencies
[!] Unable to find a specification for `TESTRely (~> 0.0.6)` depended upon by `JYPrivateLibTest0/TestController`
You have either:
* out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
* mistyped the name or version.
* not added the source repo that hosts the Podspec to your Podfile.
Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.
- 驗證本地的.podspec文件,命令如下:
$ pod lib lint --sources=https://git.asd.net/pod/TESTRelyLibrary.git,https://github.com/CocoaPods/Specs.git --allow-warnings
Cloning spec repo `asd-pod-testrelylibrary` from `https://git.asd.net/pod/TESTRelyLibrary.git`
-> JYPrivateLibTest0 (1.0.2)
- NOTE | [JYPrivateLibTest0/TextField, JYPrivateLibTest0/Constant, JYPrivateLibTest0/NetworkService, and more...] xcodebuild: note: Using new build system
- NOTE | [JYPrivateLibTest0/TextField, JYPrivateLibTest0/Constant, JYPrivateLibTest0/NetworkService, and more...] xcodebuild: note: Planning build
- NOTE | [JYPrivateLibTest0/TextField, JYPrivateLibTest0/Constant, JYPrivateLibTest0/NetworkService, and more...] xcodebuild: note: Constructing build description
- NOTE | [JYPrivateLibTest0/TextField, JYPrivateLibTest0/Constant, JYPrivateLibTest0/NetworkService, and more...] xcodebuild: warning: Skipping code signing because the target does not have an Info.plist file. (in target 'App')
JYPrivateLibTest0 passed validation.
注意:
這里驗證命令不能直接使用$ pod lib lint
灰羽,這樣會報找不到該私有庫中依賴的其他私有庫驮履,導(dǎo)致驗證通不過,后邊必須通過--sources
命令添加其他私有庫和公共庫的索引庫地址廉嚼,且用“,”隔開玫镐,如:$ pod lib lint --sources=https://git.asd.net/pod/TESTRelyLibrary.git,https://github.com/CocoaPods/Specs.git
。運行pod sepc lint
怠噪、pod repo push [REPO] [NAME.podspec]
命令時恐似,也需要通過--sources
命令添加其他私有庫和公共庫的索引庫地址,否則也會驗證通不過傍念。
驗證不通過矫夷,錯誤信息如下:
$ pod lib lint
-> JYPrivateLibTest0 (1.0.2)
- ERROR | [iOS] unknown: Encountered an unknown error (Unable to find a specification for `TESTRely (~> 0.0.6)` depended upon by `JYPrivateLibTest0/TestController`
You have either:
* out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
* mistyped the name or version.
* not added the source repo that hosts the Podspec to your Podfile.
Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.
) during validation.
[!] JYPrivateLibTest0 did not pass validation, due to 1 error.
You can use the `--no-clean` option to inspect any issue.
運行g(shù)it命令,提交修改到遠(yuǎn)程端私有代碼庫捂寿;
驗證遠(yuǎn)程端.podspec文件口四,命令:
$ pod spec lint --sources=https://git.asd.net/pod/TESTRelyLibrary.git,https://github.com/CocoaPods/Specs.git --allow-warnings
- 將.podspec文件提交到遠(yuǎn)程端私有索引庫,命令:
$ pod repo push JYPrivateRepoTest0 JYPrivateLibTest0.podspec --sources=https://git.asd.net/pod/TESTRelyLibrary.git,https://github.com/CocoaPods/Specs.git --allow-warnings
- 項目中驗證秦陋,注意別忘了通過
source
引入私有庫對應(yīng)的私有索引庫地址蔓彩。
四、私有庫中依賴第三方公共庫
私有庫中引入Cocoapods中的公共庫,包含兩種情況赤嚼。
1. 引入的公共庫中不包含動態(tài)文件(.framework)旷赖、靜態(tài)文件(.a)
在制作我自己私有Pod時,我們往往需要用到第三方提供的工具包更卒,比如說網(wǎng)絡(luò)請求Alamofire等孵、圖片加載SDWebImage等,對于這些只有源代碼文件的框架的使用是很簡單的蹂空,我們在制作Pod的時候俯萌,只需要在.podspec文件中直接通過s.dependency
引入即可,如:s.dependency 'Alamofire', '~> 4.8.1'
上枕。添加咐熙、驗證、上傳步驟請參考上邊辨萍。
具體配置信息如下:
Pod::Spec.new do |s|
...
// 這里省略沒改變的配置
...
s.subspec 'NetworkService' do |ns|
ns.source_files = 'JYPrivateLibTest0/Classes/NetworkService/*'
ns.dependency 'Alamofire', '~> 4.8.1'
end
end
當(dāng)執(zhí)行pod install
命令時棋恼,Pod會自己檢測并且install我所引用到的第三方倉庫。
2. 引入的公共庫中包含動態(tài)文件(.framework)锈玉、靜態(tài)文件(.a)
有時呢爪飘,我們也會用到諸如ShareSDK分享、高德地圖等制作成動態(tài)庫(framework)拉背、靜態(tài)庫(library/.a)方式的第三方庫师崎,其中有些庫是給你提供了Pod方式導(dǎo)入的,有些沒有提供去团。下面讓我們都試試吧抡诞。
這里以ShareSDK為例。
1). 提供了Pod方式導(dǎo)入的土陪,可能你會想到直接通過dependency依賴昼汗,如下:
Pod::Spec.new do |s|
...
// 這里省略沒改變的配置
...
s.static_framework = true # 是否包含靜態(tài)庫框架(注意:不能寫在subspec子模塊中)
s.subspec 'ShareService' do |ss|
ss.dependency 'mob_sharesdk', '~>4.2.3'
ss.dependency 'mob_sharesdk/ShareSDKPlatforms/QQ', '~>4.2.3'
ss.dependency 'mob_sharesdk/ShareSDKPlatforms/SinaWeibo', '~>4.2.3'
ss.dependency 'mob_sharesdk/ShareSDKPlatforms/WeChat', '~>4.2.3'
ss.dependency 'mob_sharesdk/ShareSDKUI', '~>4.2.3'
ss.dependency 'mob_sharesdk/ShareSDKExtension', '~>4.2.3'
end
end
這樣引入是沒問題的,可以通過pod lib lint
鬼雀、pod sepc lint
命令的驗證顷窒,提交到遠(yuǎn)程端的私有代碼庫。在項目中測試源哩,是沒有問題的鞋吉,可以引入和使用,如下圖:
遇到的錯誤:
如果你在pod lib lint
驗證時励烦,遇到如下錯誤谓着,導(dǎo)致驗證不通過,說明你沒有配置s.static_framework = true
坛掠,因為你使用了動態(tài)庫(.framework)赊锚、靜態(tài)庫(.a)治筒,如果use_frameworks!指定時,pod應(yīng)包含靜態(tài)庫框架舷蒲,所以需要允許靜態(tài)庫的使用耸袜。錯誤信息如下:
$ pod lib lint JYPrivateLibTest0.podspec
-> JYPrivateLibTest0 (1.0.4)
- ERROR | [iOS] unknown: Encountered an unknown error (The 'Pods-App' target has transitive dependencies that include static binaries: (/private/var/folders/qt/d9rd9h7n2m3cb9014qph7xkm0000gn/T/CocoaPods-Lint-20190320-5532-92gozf-JYPrivateLibTest0/Pods/mob_sharesdk/ShareSDK/ShareSDK.framework, /private/var/folders/qt/d9rd9h7n2m3cb9014qph7xkm0000gn/T/CocoaPods-Lint-20190320-5532-92gozf-JYPrivateLibTest0/Pods/mob_sharesdk/ShareSDK/Support/Required/ShareSDKConnector.framework, /private/var/folders/qt/d9rd9h7n2m3cb9014qph7xkm0000gn/T/CocoaPods-Lint-20190320-5532-92gozf-JYPrivateLibTest0/Pods/mob_sharesdk/ShareSDK/Support/Optional/ShareSDKExtension.framework, /private/var/folders/qt/d9rd9h7n2m3cb9014qph7xkm0000gn/T/CocoaPods-Lint-20190320-5532-92gozf-JYPrivateLibTest0/Pods/mob_sharesdk/ShareSDK/Support/PlatformSDK/QQSDK/TencentOpenAPI.framework, /private/var/folders/qt/d9rd9h7n2m3cb9014qph7xkm0000gn/T/CocoaPods-Lint-20190320-5532-92gozf-JYPrivateLibTest0/Pods/mob_sharesdk/ShareSDK/Support/PlatformConnector/QQConnector.framework, /private/var/folders/qt/d9rd9h7n2m3cb9014qph7xkm0000gn/T/CocoaPods-Lint-20190320-5532-92gozf-JYPrivateLibTest0/Pods/mob_sharesdk/ShareSDK/Support/PlatformSDK/SinaWeiboSDK/libWeiboSDK.a, /private/var/folders/qt/d9rd9h7n2m3cb9014qph7xkm0000gn/T/CocoaPods-Lint-20190320-5532-92gozf-JYPrivateLibTest0/Pods/mob_sharesdk/ShareSDK/Support/PlatformConnector/SinaWeiboConnector.framework, /private/var/folders/qt/d9rd9h7n2m3cb9014qph7xkm0000gn/T/CocoaPods-Lint-20190320-5532-92gozf-JYPrivateLibTest0/Pods/mob_sharesdk/ShareSDK/Support/PlatformSDK/WeChatSDK/libWeChatSDK.a, /private/var/folders/qt/d9rd9h7n2m3cb9014qph7xkm0000gn/T/CocoaPods-Lint-20190320-5532-92gozf-JYPrivateLibTest0/Pods/mob_sharesdk/ShareSDK/Support/PlatformConnector/WechatConnector.framework, and /private/var/folders/qt/d9rd9h7n2m3cb9014qph7xkm0000gn/T/CocoaPods-Lint-20190320-5532-92gozf-JYPrivateLibTest0/Pods/mob_sharesdk/ShareSDK/Support/Optional/ShareSDKUI.framework)) during validation.
[!] JYPrivateLibTest0 did not pass validation, due to 1 error.
You can use the `--no-clean` option to inspect any issue.
以上錯誤信息解讀:在驗證過程中,遇到一個未知的錯誤(' podcast - app '目標(biāo)有傳遞依賴關(guān)系牲平,包括動靜態(tài)二進(jìn)制文件堤框。
2). 這種不管能不能pod導(dǎo)入,都要下載你需要的SDK包纵柿,手動導(dǎo)入蜈抓。以ShareSDK為例,首先在ShareSDK官網(wǎng)下載你所需要的ShareSDK包昂儒,然后將下載的ShareSDK包资昧,導(dǎo)入到你的私有庫的Classes文件夾下,再然后配置你的.podspec文件荆忍。(這里僅僅是導(dǎo)入第三方庫,不包含其他文件)
.podspec文件配置如下:
Pod::Spec.new do |s|
...
// 這里省略沒改變的配置
...
# 是否包含靜態(tài)庫框架(注意:不能寫在subspec子模塊中)
s.static_framework = true
s.subspec 'ShareService' do |ss|
# 文件的路徑和公開頭文件路徑
#ss.source_files = 'JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/**/*.framework/Headers/*.h'
#ss.public_header_files = 'JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/**/*.framework/Headers/*.h'
# ShareSDK的所有動態(tài)庫路徑(也可以寫具體的路徑撤缴,ShareSDK的framework太多了刹枉,偷懶一下)
ss.vendored_frameworks = 'JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/**/*.framework'
# 第三方的靜態(tài)文件路徑
ss.vendored_libraries = 'JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/ShareSDK/Support/PlatformSDK/**/*.a'
# 第三方的資源文件
ss.resources = 'JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/ShareSDK/Support/**/*.bundle'
# 第三方用到的系統(tǒng)動態(tài)庫
ss.frameworks = 'UIKit', 'JavaScriptCore', 'ImageIO'
# 第三方用到的系統(tǒng)靜態(tài)文件(前面的lib要去掉,否則會報錯)
ss.libraries = 'icucore', 'z', 'c++', 'sqlite3'
# Build Settings里邊的設(shè)置
ss.pod_target_xcconfig = {
#'FRAMEWORK_SEARCH_PATHS' => '${PODS_ROOT}/JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK',
'HEADER_SEARCH_PATHS' => '$(PODS_ROOT)/JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/**/*.framework/Headers',
'LD_RUNPATH_SEARCH_PATHS' => '$(PODS_ROOT)/JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/',
'OTHER_LDFLAGS' => ['-ObjC']
}
end
end
將修改提交到遠(yuǎn)程端私有代碼庫屈呕,通過pod lib lint
微宝、pod sepc lint
命令驗證,并提交到遠(yuǎn)程端的私有代碼庫虎眨。
注意:
s.static_framework = true 必須和s.name同級蟋软,不能寫在s.subspec子模塊中,否則回報錯誤嗽桩。
遇到的問題:
demo工程pod install
后岳守,編譯運行,以及pod lib lint
驗證時都會報以下錯誤碌冶,錯誤信息如下:
$ pod lib lint --sources=https://git.asd.net/pod/TESTRelyLibrary.git,https://github.com/CocoaPods/Specs.git --allow-warnings
-> JYPrivateLibTest0 (1.0.5)
- ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code. You can use `--verbose` for more information.
- NOTE | [JYPrivateLibTest0/Constant, JYPrivateLibTest0/TextField, JYPrivateLibTest0/NetworkService, and more...] xcodebuild: note: Using new build system
- NOTE | [JYPrivateLibTest0/Constant, JYPrivateLibTest0/TextField, JYPrivateLibTest0/NetworkService, and more...] xcodebuild: note: Planning build
- NOTE | [JYPrivateLibTest0/Constant, JYPrivateLibTest0/TextField, JYPrivateLibTest0/NetworkService, and more...] xcodebuild: note: Constructing build description
- NOTE | [JYPrivateLibTest0/Constant, JYPrivateLibTest0/TextField, JYPrivateLibTest0/NetworkService, and more...] xcodebuild: warning: Skipping code signing because the target does not have an Info.plist file. (in target 'App')
- NOTE | xcodebuild: <module-includes>:1:9: note: in file included from <module-includes>:1:
- NOTE | [iOS] xcodebuild: //privateTarget Support Files/JYPrivateLibTest0/JYPrivateLibTest0-umbrella.h:45:9: note: in file included from //privateTarget Support Files/JYPrivateLibTest0/JYPrivateLibTest0-umbrella.h:45:
- ERROR | [iOS] xcodebuild: /Users/123/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/Required/MOBFoundation.framework/Headers/MOBFOAuthService.h:9:9: error: include of non-modular header inside framework module 'JYPrivateLibTest0.MOBFOAuthService': '/Users/123/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/Required/MOBFoundation.framework/Headers/MOBFoundation.h'
- NOTE | [iOS] xcodebuild: //privateTarget Support Files/JYPrivateLibTest0/JYPrivateLibTest0-umbrella.h:64:9: note: in file included from //privateTarget Support Files/JYPrivateLibTest0/JYPrivateLibTest0-umbrella.h:64:
- ERROR | [iOS] xcodebuild: /Users/123/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/ShareSDK/ShareSDK.framework/Headers/ShareSDK+Base.h:9:9: error: include of non-modular header inside framework module 'JYPrivateLibTest0.ShareSDK_Base': '/Users/123/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/ShareSDK/ShareSDK.framework/Headers/ShareSDK.h'
- NOTE | xcodebuild: //privateTarget Support Files/JYPrivateLibTest0/JYPrivateLibTest0-umbrella.h:84:9: note: in file included from //privateTarget Support Files/JYPrivateLibTest0/JYPrivateLibTest0-umbrella.h:84:
- ERROR | [iOS] xcodebuild: /Users/123/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/ShareSDK/Support/Optional/ShareSDKUI.framework/Headers/ShareSDKUI.h:13:9: error: include of non-modular header inside framework module 'JYPrivateLibTest0.ShareSDKUI': '/Users/123/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/ShareSDK/Support/Optional/ShareSDKUI.framework/Headers/SSUIEditorConfiguration.h'
- ERROR | [iOS] xcodebuild: /Users/123/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/ShareSDK/Support/Optional/ShareSDKUI.framework/Headers/ShareSDKUI.h:14:9: error: include of non-modular header inside framework module 'JYPrivateLibTest0.ShareSDKUI': '/Users/asd/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/ShareSDK/Support/Optional/ShareSDKUI.framework/Headers/SSUIShareSheetConfiguration.h'
- ERROR | [iOS] xcodebuild: /Users/asd/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/ShareSDK/Support/Optional/ShareSDKUI.framework/Headers/ShareSDKUI.h:15:9: error: include of non-modular header inside framework module 'JYPrivateLibTest0.ShareSDKUI': '/Users/asd/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/ShareSDK/Support/Optional/ShareSDKUI.framework/Headers/SSUIPlatformItem.h'
- NOTE | [iOS] xcodebuild: <unknown>:0: error: could not build Objective-C module 'JYPrivateLibTest0'
- WARN | [JYPrivateLibTest0/TestController] xcodebuild: /Users/asd/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/TestController/JYFather.swift:9:8: warning: file 'JYFather.swift' is part of module 'JYPrivateLibTest0'; ignoring import
- WARN | [JYPrivateLibTest0/TestController, JYPrivateLibTest0/OCBase64, JYPrivateLibTest0/OCBase64/Base64, and more...] xcodebuild: /Users/asd/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/OCBase64/Base64/Base64.m:63:63: warning: implicit conversion loses integer precision: 'long long' to 'NSUInteger' (aka 'unsigned int') [-Wshorten-64-to-32]
- WARN | [JYPrivateLibTest0/TestController, JYPrivateLibTest0/OCBase64, JYPrivateLibTest0/OCBase64/Base64, and more...] xcodebuild: /Users/asd/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/OCBase64/Base64/Base64.m:91:25: warning: implicit conversion loses integer precision: 'long long' to 'NSUInteger' (aka 'unsigned int') [-Wshorten-64-to-32]
- WARN | [JYPrivateLibTest0/TestController, JYPrivateLibTest0/OCBase64, JYPrivateLibTest0/OCBase64/Base64, and more...] xcodebuild: /Users/asd/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/OCBase64/Base64/Base64.m:107:58: warning: implicit conversion loses integer precision: 'long long' to 'unsigned long' [-Wshorten-64-to-32]
- WARN | [JYPrivateLibTest0/TestController, JYPrivateLibTest0/OCBase64, JYPrivateLibTest0/OCBase64/Base64, and more...] xcodebuild: /Users/asd/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/OCBase64/Base64/Base64.m:147:44: warning: implicit conversion loses integer precision: 'long long' to 'unsigned long' [-Wshorten-64-to-32]
- WARN | [JYPrivateLibTest0/TestController, JYPrivateLibTest0/OCBase64, JYPrivateLibTest0/OCBase64/Base64, and more...] xcodebuild: /Users/asd/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/OCBase64/Base64/Base64.m:149:54: warning: implicit conversion loses integer precision: 'long long' to 'NSUInteger' (aka 'unsigned int') [-Wshorten-64-to-32]
[!] JYPrivateLibTest0 did not pass validation, due to 6 errors.
You can use the `--no-clean` option to inspect any issue.
上面信息的摘仁 :
error: include of non-modular header inside framework module 'JYPrivateLibTest0.ShareSDK_Base': '/Users/asd/Desktop/PrivateRepository/JYPrivateLibTest0/JYPrivateLibTest0/Classes/ShareService/JYMobShareSDK/ShareSDK/ShareSDK.framework/Headers/ShareSDK.h'
要解決這個錯誤其實很簡單,只需要注釋掉或刪除掉ShareService子模塊中的ss.source_files和ss.public_header_files這兩個參數(shù)及配置即可扑庞。
那報這個錯誤是什么原因造成的呢譬重?
在創(chuàng)建Pod,且引入Objective-C語言開發(fā)的第三方公共庫供Swift使用時罐氨,我們并不需要創(chuàng)建xxx-Bridge-Header.h橋文件去引入Objective-C的頭文件臀规, 這個工作是交由xxx-umbrella.h
文件完成,這個文件的其中一個作用:其實和xxx-Bridge-Header.h橋文件的作用基本相同栅隐,向外界暴露Objective-C的頭文件供Swift使用塔嬉,實現(xiàn)Swift和Objective-C的混編玩徊。當(dāng)你再次通過ss.source_files和ss.public_header_files暴露第三方公共的頭文件時會重復(fù)定義,所以需要注釋掉或刪除掉ss.source_files和ss.public_header_files這兩個參數(shù)及配置邑遏。讓我們試試能否成功吧佣赖,結(jié)果是肯定的。
-
優(yōu)化(僅限手動導(dǎo)入的第三方)
通過以上的第三方公庫的導(dǎo)入已經(jīng)是可以使用了记盒。但是呢憎蛤,你可能會想到如果你的項目主要是采用Swift語言來寫的,那么你就必須要創(chuàng)建xxx-Bridge-Heder.h橋文件來引入Objective-C的頭文件纪吮,那有沒有一種方式是可以不需要創(chuàng)建xxx-Bridge-Header.h橋文件的呢俩檬?
為了使你更好的了解,在這里我新創(chuàng)建了一個私有代碼庫JYPLibTest1碾盟,且使用百度地圖Lib來演示棚辽,然后通過subspec在.podsepc中創(chuàng)建百度地圖的子模塊JYBaiDuMapKit(子模塊文件夾名字,可隨意缺取)屈藐。目錄如下:
解決方案:
讓我們來優(yōu)化一下吧,這里我將創(chuàng)建一個.modulemap文件來解決這個問題熙尉,讓我們修改.podspec联逻,為所引用到的framework創(chuàng)建Module。
注意:
如果我們手動創(chuàng)建一個. modulemap文件检痰,然后直接將該文件拖到相應(yīng)的目錄下包归,這樣在 pod install
時可能會導(dǎo)致丟失該文件,那么我們應(yīng)該怎么辦呢铅歼?解決辦法是公壤,我們需要使用prepare_command屬性,來幫助我們自動創(chuàng)建.modulemap文件椎椰。
prepare_command屬性的解釋厦幅、使用場景及禁用條件:
prepare_command屬性是下載Pod后將執(zhí)行的bash腳本。此命令可用于創(chuàng)建慨飘、刪除和修改下載的任何文件慨削,并將在收集規(guī)范的其他文件屬性的任何路徑之前運行。
此命令在清理Pod和創(chuàng)建Pods項目之前執(zhí)行套媚。工作目錄是Pod的根目錄缚态。
prepare_command屬性必須在主模塊
中使用。
如果pod安裝了:path選項堤瘤,則不會執(zhí)行此命令玫芦。
具體配置如下:
Pod::Spec.new do |s|
s.name = 'JYPLibTest1'
s.version = '1.0.0'
s.summary = '另一個測試私有庫'
s.homepage = 'https://git.artron.net/CocoaPods/JYPLibTest1'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'JYanshao' => '654565181@qq.com' }
s.source = { :git => 'https://git.123.net/CocoaPods/JYPLibTest1.git', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
s.source_files = 'JYPLibTest1/Classes/**/*.swift'
s.swift_version = '4.2'
s.subspec 'JYBaiDuMapKit' do |mk|
mk.vendored_frameworks = 'JYPLibTest1/Classes/JYBaiDuMapKit/*.framework'
mk.vendored_libraries = 'JYPLibTest1/Classes/JYBaiDuMapKit/thirdlibs/*.a'
mk.resources = 'JYPLibTest1/Classes/JYBaiDuMapKit/BaiduMapAPI_Map.framework/mapapi.bundle'
mk.frameworks = 'CoreLocation', 'QuartzCore', 'OpenGLES', 'SystemConfiguration', 'CoreGraphics', 'Security', 'CoreTelephony'
mk.libraries = 'sqlite3', 'c++'
mk.preserve_paths = 'JYPLibTest1/Classes/JYBaiDuMapKit/*.framework', 'JYPLibTest1/Classes/JYBaiDuMapKit/thirdlibs/*.a'
mk.pod_target_xcconfig = {
'HEADER_SEARCH_PATHS' => '$(PODS_ROOT)/JYPLibTest1/Classes/JYBaiDuMapKit/*.framework/Headers',
'LD_RUNPATH_SEARCH_PATHS' => '$(PODS_ROOT)/JYPLibTest1/Classes/JYBaiDuMapKit/',
'OTHER_LDFLAGS' => '-ObjC'
}
end
# prepare_command屬性必須在主模塊中使用
s.prepare_command = <<-EOF
# 創(chuàng)建BaiduMapAPI_Base Module
rm -rf JYPLibTest1/Classes/JYBaiDuMapKit/BaiduMapAPI_Base.framework/Modules
mkdir JYPLibTest1/Classes/JYBaiDuMapKit/BaiduMapAPI_Base.framework/Modules
touch JYPLibTest1/Classes/JYBaiDuMapKit/BaiduMapAPI_Base.framework/Modules/module.modulemap
cat <<-EOF > JYPLibTest1/Classes/JYBaiDuMapKit/BaiduMapAPI_Base.framework/Modules/module.modulemap
framework module BaiduMapAPI_Base {
umbrella header "BMKBaseComponent.h"
export *
link "sqlite3"
link "c++"
}
\EOF
# 創(chuàng)建BaiduMapAPI_Map Module
rm -rf JYPLibTest1/Classes/JYBaiDuMapKit/BaiduMapAPI_Map.framework/Modules
mkdir JYPLibTest1/Classes/JYBaiDuMapKit/BaiduMapAPI_Map.framework/Modules
touch JYPLibTest1/Classes/JYBaiDuMapKit/BaiduMapAPI_Map.framework/Modules/module.modulemap
cat <<-EOF > JYPLibTest1/Classes/JYBaiDuMapKit/BaiduMapAPI_Map.framework/Modules/module.modulemap
framework module BaiduMapAPI_Map {
umbrella header "BMKMapComponent.h"
export *
link "sqlite3"
link "c++"
}
\EOF
EOF
end
配置完成,讓我們更新一下demo工程本辐,測試一下是否可以使用桥帆。在測試項目中的使用和在自己私有庫中的使用医增,結(jié)果如下圖:相同的方法在ShareSDK相應(yīng)的framework目錄下創(chuàng)建Module卻出現(xiàn)了錯誤,暫時未解決老虫,有興趣的朋友可以試試叶骨,分享一下。
五祈匙、私有庫中Swift和Objective-C混編(兩種情況)
這里我門先看一下忽刽,混編的兩種情況的文件目錄結(jié)構(gòu),然后再一步一步的往下走夺欲,目錄結(jié)構(gòu)如下:
├── JYPLibTest1
│ ├── Assets
│ ├── Classes
│ │ ├── OCClass # Objective-C類的文件夾(OCClass子模塊)
│ │ │ ├── JYFamily.h # 家庭類(NSObject)
│ │ │ ├── JYFamily.m
│ │ │ ├── JYFather.swift # 父親類(NSObject)
│ │ │ ├── JYKid.h # 孩子類(NSObject)
│ │ │ ├── JYKid.m
│ │ │ ├── JYMother.swift # 母親類(NSObject)
│ │ │ ├── JYPLibTest1.h # 頭文件(項目要求要有的)
│ │ │ └── JYPersonProtocol.h # 協(xié)議類
│ │ ├── SwiftClass # Swift類的文件夾(SwiftClass子模塊)
│ │ │ ├── JYFather2.swift # 父親類2(NSObject)
│ │ │ └── JYMother2.swift # 母親類2(NSObject)
1. 同一個模塊(OCClass)內(nèi)的Swift和Objective-C混編
一個層面問題的解決跪帝,又伴隨著另一層面的思考,那就是如何在私有庫中實現(xiàn)Swfit和Objective-C的混編及混合打包(我們這一步只驗證Swift與Objective-C混合打包)些阅。
同一個模塊(OCClass)內(nèi)的Swift和Objective-C混編伞剑,可以是單向調(diào)用,即Swift調(diào)用Objective-C市埋,或者Objective-C調(diào)用Swift黎泣,也可以是雙向調(diào)用,即Swift調(diào)用Objective-C缤谎,Objective-C又調(diào)用Swift聘裁。
在這里我們繼續(xù)使用JYPLibTest1私有庫,且以雙向調(diào)用為例弓千。這個問題讓我們通過一個案例來看,能更好的理解献起。
案例:一個周末的早上洋访,家中的父母做好早餐,叫孩子起床谴餐,喂他/她吃飯姻政。(一個家庭中,包括父母和孩子岂嗓,父母中又包括孩子汁展,父母、孩子都有吃的動作厌殉,孩子吃飯是由父母喂的)食绿。
- 首先讓我們創(chuàng)建一個JYKid(孩子)類和一個JYPersonProtocol協(xié)議類,這兩個類都是Objective-C類公罕。接下來實現(xiàn)這兩個類器紧,代碼如下:
/// JYKid.h
#import <Foundation/Foundation.h>
#import "JYPersonProtocol.h"
@interface JYKid : NSObject <JYPersonProtocol> // 遵循協(xié)議
@property (nonatomic, strong) NSString *name;
@end
/// JYKid.m
#import "JYKid.h"
@implementation JYKid
/// 實現(xiàn)JYPersonProtocol協(xié)議方法
- (void)eat {
NSLog(@"%@ is eating", self.name != nil ? self.name : @"Kid");
}
@end
/// JYPersonProtocol.h
#import <Foundation/Foundation.h>
@protocol JYPersonProtocol <NSObject>
@optional
- (void)eat;
@end
完成后,我們的這兩個類肯定是需要給外部文件(Objective-C/Swift)使用的楼眷,那么該如何處理呢铲汪?其實解決辦法很簡單熊尉,只需將Objective-C類的.h文件設(shè)置為public即可。以JYKid.h為例掌腰,具體設(shè)置如下圖:相同的方法狰住,將JYPersonProtocol.h也設(shè)置為public。有的文件創(chuàng)建完默認(rèn)就是public齿梁,那就可以略過此步了催植。
設(shè)置完成,修改.podspec文件士飒,內(nèi)容如下:
Pod::Spec.new do |s|
s.name = 'JYPLibTest1'
s.version = '1.0.1'
s.summary = '另一個測試私有庫'
s.homepage = 'https://git.artron.net/CocoaPods/JYPLibTest1'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'JYanshao' => '654565181@qq.com' }
s.source = { :git => 'https://git.artron.net/CocoaPods/JYPLibTest1.git', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
s.source_files = 'JYPLibTest1/Classes/**/*.swift'
s.subspec 'OCClass' do |cc|
cc.source_files = 'JYPLibTest1/Classes/OCClass/*.{h,m}'
end
end
在終端執(zhí)行下pod install
命令查邢,更新下demo工程,編譯運行沒有錯誤酵幕。然后打開demo中的xxx-umbrella.h文件扰藕,你會發(fā)現(xiàn)JYKid和JYPersonProtocol兩個文件的頭文件已經(jīng)被自動引入進(jìn)來了。如下圖:
xxx-umbrella.h文件可以被看成是你項目中橋接文件xxx-Bridge-Header.h芳撒,也可以看成是一個Objective-C的頭文件邓深。
讓我們繼續(xù),創(chuàng)建兩個Swift類JYFather和JYMother笔刹,然后實現(xiàn)Swift對Objective-C類的引用芥备,使其有一個小孩JYKid并且實現(xiàn)JYPersonProtocol協(xié)議,然后喂這個小孩吃飯舌菜。
注意:
Swift類與Objective-C類有些區(qū)別萌壳,Swift類不需要像Objective-C類一樣設(shè)置他們的頭文件為public,Swift類只需要定義其文件的訪問權(quán)限即可日月。
JYFather和JYMother文件中的代碼一樣袱瓮,以JYFather為例,代碼如下:
/// JYFather.swift / JYMother.swift 這兩個文件中的代碼一樣爱咬,copy一下
/// 父母這兩個文件都繼承JYPersonProtocol協(xié)議尺借,并實現(xiàn)其方法
import UIKit
open class JYFather: NSObject, JYPersonProtocol {
var name: String = ""
var kid: JYKid?
public init(name: String, kid: JYKid) {
super.init()
self.name = name
self.kid = kid
}
@objc public func feed(_ food: String) {
print("\(name) is feeding \(kid?.name ?? "kid") eat \(food)")
}
/// 實現(xiàn)協(xié)議方法
public func eat() {
print("\(name) is eating")
}
}
修改.podspec文件,配置如下:
Pod::Spec.new do |s|
...
# 沒有變化的部分省略了
...
s.subspec 'OCClass' do |cc|
cc.source_files = 'JYPLibTest1/Classes/OCClass/*.{h,m,swift}'
end
end
執(zhí)行pod install
精拟,更新demo燎斩,編譯運行,結(jié)果報錯了蜂绎,錯誤如下:
提示我們沒有找到JYPLibTest1.h文件栅表,因為項目中根本就沒有這個文件,所以才找不到师枣,既然它需要這么一個文件谨读,那就按它的意思創(chuàng)建一個JYPLibTest1.h頭文件,并 #import 引入已經(jīng)創(chuàng)建的Objective-C類頭文件坛吁。
注意:
JYPLibTest1頭文件劳殖,是一個Objective-C類的頭文件铐尚。用來導(dǎo)入Objective-C類的頭文件用的,相當(dāng)于xxx-Bridging-Header.h文件哆姻。
更新demo宣增,并編譯運行發(fā)現(xiàn)沒有問題了。
到這里矛缨,我們創(chuàng)建了父母爹脾、孩子、以及吃的協(xié)議類箕昭,接下來讓我們創(chuàng)建一個Objective-C的家庭類JYFamily灵妨,把他們組合成一個家庭吧,這樣才圓滿落竹,并實現(xiàn)Objective-C類調(diào)用Swift類泌霍。
JYFamily類的代碼如下:
/// JYFamily.h
#import <Foundation/Foundation.h>
#import "JYKid.h"
@class JYFather, JYMother; // 這里有個問題需注意,后面會講到
@interface JYFamily : NSObject
@property (nonatomic, strong) JYKid *kid;
@property (nonatomic, strong) JYFather *father;
@property (nonatomic, strong) JYMother *mother;
// 打印父母各自的喂食
- (void)feed:(NSString *)fFood mFood:(NSString *)mFood;
@end
/// JYFamily.m
#import "JYFamily.h"
#import <JYPLibTest1/JYPLibTest1-Swift.h>
@implementation JYFamily
- (void)feed:(NSString *)fFood mFood:(NSString *)mFood {
[self.father feed:fFood]; // 父親喂孩子吃食物
[self.mother feed:mFood]; // 母親喂孩子吃食物
}
@end
更新demo述召,并編譯運行朱转,發(fā)現(xiàn)沒有錯誤。然后在測試項目中引入积暖,并測試是否可用藤为。我的測試結(jié)果如下:
本地和遠(yuǎn)程驗證也是可以通過的,上傳也是成功的夺刑。
這里有個問題需要注意一下
如果你在JYFamily.h文件中直接引入#import "JYPLibTest1-Swift.h"
頭文件的話缅疟,編譯運行demo可能會報如下錯誤。
原因有兩點:1). 在你的ProjectName-Swift.h中是引用了JYFamily.h的遍愿,如果你這時候在定義JYFamily.h中又引用ProjectName-Swift.h造成了有點像循環(huán)引用的概念存淫,所以在JYFamily.h中只需要用@Class
聲明一下用到的文件即可,在JYFamily.m中在真正引用需要用到的文件错览;
(下面這張圖片是借用的凌彬,原文章在下邊的參考文章部分有鏈接)
2). Swift只支持動態(tài)庫弯淘,但并非完全意義的動態(tài)庫,而我們的代碼在Pod之后實際上是一個動態(tài)的Framework寇荧,Swift是有命名空間的一個概念刽脖,這時候你需要做的是在引用時需要寫明命名空間羞海。
基于上述兩點原因,我們只能在Objective-C類的JYFamily.m文件中引用(#import)并且加上命名空間曲管,而JYFamily.h文件中則用 @Class 聲明一下引用的類却邓。最終結(jié)果如下圖:
解決完這個問題,記得更新demo院水,編譯運行腊徙。
2.不同模塊內(nèi)的Swift和Objective-C的混編
不同模塊內(nèi)的Swift和Objective-C混編简十,可以是單向調(diào)用,即Swift調(diào)用Objective-C撬腾,或者Objective-C調(diào)用Swift螟蝙,也可以是雙向調(diào)用,但有些限制民傻,不是很靈活胰默。
緊接著第一種情況,我們來探索一下第二種情況(還是以雙向引用為例)漓踢。
我們還使用上面OCClass子模塊中的Objective-C類牵署,然后在SwiftClass文件夾下創(chuàng)建Swift類JYFather2和JYMother2兩個文件,這兩個文件中的代碼是copy的JYFather和JYMother兩個文件中的代碼喧半。
完成以上步驟薯酝,修改.podspec文件的配置半沽,因為是兩個不同的子模塊之間的混編,所以需要通過dependency
來引入另一個模塊供本模塊使用吴菠,具體配置如下:
Pod::Spec.new do |s|
...
# 不變的配置省略
...
s.subspec 'OCClass' do |cc|
cc.source_files = 'JYPLibTest1/Classes/OCClass/*.{h,m,swift}'
#cc.dependency 'JYPLibTest1/SwiftClass' # 這里不能再依賴SwiftClass子模塊了者填,否則會造成循環(huán)依賴的問題
end
s.subspec 'SwiftClass' do |sc|
sc.source_files = 'JYPLibTest1/Classes/SwiftClass/*.swift'
sc.dependency 'JYPLibTest1/OCClass'
end
end
終端下更新demo工程,編譯運行做葵,沒有問題占哟。
但是在執(zhí)行pod lib lint
驗證時卻出現(xiàn)了錯誤,具體錯誤如下:
- ERROR | [JYPLibTest1/OCClass,JYPLibTest1/SwiftClass] xcodebuild: /Users/artron/Desktop/PrivateRepository/JYPLibTest1/JYPLibTest1/Classes/OCClass/JYFamily.m:15:6: error: receiver type 'JYFather2' for instance message is a forward declaration
- ERROR | [JYPLibTest1/OCClass,JYPLibTest1/SwiftClass] xcodebuild: /Users/artron/Desktop/PrivateRepository/JYPLibTest1/JYPLibTest1/Classes/OCClass/JYFamily.m:16:6: error: receiver type 'JYMother2' for instance message is a forward declaration
這個問題造成的原因是你的JYFamily.h文件中用了@Class
聲明了你的JYFather2和JYMother2酿矢,但是在JYFamily.m中使用的時候沒有檢測到你用#import
引入這兩個文件榨乎,所以驗證失敗。所以子模塊之間的混編會有些局限瘫筐。
子模塊之間還要注意循環(huán)依賴的問題
如上.podspec中蜜暑,cc.dependency 'JYPLibTest1/SwiftClass'
,sc.dependency 'JYPLibTest1/OCClass'
兩個子模塊都互相依賴了對方策肝,這時執(zhí)行pod install
肛捍,會報JYPLibTest1/SwiftClass
和JYPLibTest1/OCClass
之間存在循環(huán)依賴關(guān)系的問題,解決方法就是斷開一方的依賴即可之众。
具體錯誤如下:
以上若有不妥請指正拙毫。
參考文章:
Build with CocoaPods
使用私有Cocoapods倉庫 中高級用法
pod庫包含MRC的文件
組件化開發(fā)之-如何解決Swift/OC-Framenwork/Library混合創(chuàng)建pod問題