總結(jié)下封裝sdk遇到的一些問(wèn)題。
目的是要封裝個(gè)sdk供渠道app使用筒占,內(nèi)部會(huì)集成一些廣告商sdk贪庙,然后封裝一些網(wǎng)絡(luò)請(qǐng)求傳遞調(diào)用信息,最后打包提供給客戶止邮。
功能總體很簡(jiǎn)單,考慮到需要后期維護(hù)奏窑,選了cocoapods工具作為操作集,從初始化埃唯,到demo,到打包上傳均提供現(xiàn)成的解決方案墨叛。
問(wèn)題1
pod太慢止毕,下行速度在幾kb徘徊漠趁,搜了一波答案扁凛,用SwitchHosts將git主要節(jié)點(diǎn)加入host 闯传,又用git config --global http.https://github.com.proxy socks5://127.0.0.1:1086 將git代理到vpn端口上谨朝,效果立即提升甥绿。
問(wèn)題2
根據(jù)說(shuō)明配置好spec文件后字币,發(fā)現(xiàn)無(wú)法運(yùn)行模擬器共缕,報(bào)錯(cuò)如下:
照著最佳答案配置后洗出,問(wèn)題解決骄呼。原因是:
蘋(píng)果最新退出的m1芯片徹底排除了x86_64的指令集共苛,從Xcode12開(kāi)始蜓萄,模擬器指令集也默認(rèn)也包含了arm64隅茎,但因?yàn)楹芏嗟谌结槍?duì)模擬器編譯后的產(chǎn)物并不包含嫉沽,所以需要將模擬器的指令集中排除arm64辟犀,設(shè)置后绸硕,模擬器將不再被認(rèn)為支持arm64堂竟。
大概有以下幾種方案:
方案1
Build Settings >> Excluded Architectures added "arm64" to both Release and Debug mode for "Any iOS Simulator SDK" option.
這種方案需要將主項(xiàng)目和pod項(xiàng)目同時(shí)設(shè)置玻佩,且再次pod install后pod相關(guān)的設(shè)置會(huì)失效出嘹。
方案2
s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
需要在pod spec里增加兩行咬崔,但對(duì)于自己的pod dev項(xiàng)目可以,對(duì)于其它第三方項(xiàng)目是沒(méi)有權(quán)限的垮斯,其中pod_target_xcconfig和user_target_xcconfig的區(qū)別為:
- pod_target_xcconfig 用于當(dāng)自身pod配置
- user_target_xcconfig 用于設(shè)置調(diào)用方的配置郎仆,比如主工程兜蠕,鑒于工具不可污染調(diào)用方的原則扰肌,不建議使用熊杨。所以調(diào)用方還是建議自己在Build Setting里設(shè)置為好曙旭。
方案3
post_install do |installer|
installer.pods_project.build_configurations.each do |config|
config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
end
end
在Podfile里增加以上晶府,可以設(shè)置所有pod項(xiàng)目夷狰,一勞永逸郊霎,也是最終解決方案
方案4
- 刪除Valid Architectures 選項(xiàng)
在xcode12之前Valid Architectures用于標(biāo)識(shí)所有指令集的集合沼头,通過(guò)和standard architectures搭配得到最終需要的指令集书劝,Xcode12以后棄用Valid Architectures进倍,推出Excluded Archs來(lái)排除不支持的指令集购对,顯然指令集太多了猾昆,算交集不如算排除來(lái)得簡(jiǎn)單骡苞。
但最終不清楚是如何解決的問(wèn)題垂蜗,not work for me。
方案5
- Setting Validate Workspace to YES
不清楚具體含義贴见,Xcode12開(kāi)始有的選項(xiàng)烘苹,英文翻譯為:
If enabled, perform validation checks on the workspace configuration as part of the build process.
https://developer.apple.com/forums/thread/669274 里有個(gè)答案說(shuō)明:
Same thing happened with my project. I believe that this is an intentional change by Apple to force developers to start distributing xcframeworks with support for arm64 simulators (M1 Macs). Fat binary frameworks don't work anymore because simulators and actual devices can have the same architecture. The proper solution is to repack the GoogleCast framework into xcframework. You can do this by splitting the fat binary into two using lipo (one for simulator and one for real devices). If you don't want to do this, you can enable "Validate workspace" in build settings. This will enable you to build your project and only output a warning.
說(shuō)是打開(kāi)Validate workspace設(shè)置后片部,以上問(wèn)題只會(huì)用警告的方式輸出,不影響運(yùn)行档悠,但同樣 not word for me廊鸥。
后續(xù)查看后得知:
蘋(píng)果在Xcode12.3中統(tǒng)一驗(yàn)證了framework的合法性辖所,不在支持合成模擬器和真機(jī)的framework(因?yàn)槟M器和真機(jī)都支持arm64了)惰说,所以就會(huì)報(bào)錯(cuò)缘回,但因錯(cuò)誤類似助被,被歸結(jié)為一個(gè)問(wèn)題切诀,有點(diǎn)混淆視聽(tīng)揩环。
開(kāi)啟Validate workspace后幅虑,會(huì)將workspace錯(cuò)誤當(dāng)做警告丰滑,暫時(shí)解決問(wèn)題倒庵,同樣的褒墨,所有錯(cuò)誤都會(huì)被當(dāng)做警告擎宝,風(fēng)險(xiǎn)未知郁妈。
鏈接:https://stackoverflow.com/questions/63267897/building-for-ios-simulator-but-the-linked-framework-framework-was-built/65306886
至此 該問(wèn)題解決绍申,從搜索到的文章數(shù)量來(lái)看噩咪,Xcode12 絕大部分問(wèn)題都因?yàn)閙1芯片引發(fā)极阅,吐槽者甚眾胃碾,模擬器從誕生起就和真機(jī)是兩碼事筋搏,很多第三方服務(wù)都得通過(guò)打包合成的方式提供服務(wù)仆百,突然被暫停影響面太大了奔脐。
----------------------開(kāi)始打包----------------------
問(wèn)題3
- 隱藏.h文件private_header_files 設(shè)置后不生效俄周。
- 解決
pod默認(rèn)會(huì)將所有.h設(shè)為公開(kāi),設(shè)置public_header_files后將只讀取其中的.h作為公開(kāi)類峦朗。
問(wèn)題4
- 執(zhí)行
pod lib lint SMSDK.podspec --verbose --allow-warnings - 報(bào)錯(cuò)
missing compatible arch in /Library/Ruby/Gems/2.6.0/gems/ffi-1.14.2/lib/ffi_c.bundle - /Library/Ruby/Gems/2.6.0/gems/ffi-1.14.2/lib/ffi_c.bundle - 解決
ffi-1.14.2不支持m1芯片建丧,命令增加arch -x86_64前綴甚垦,解決問(wèn)題茶鹃。通過(guò)將終端app設(shè)置為Rosetta模式無(wú)效艰亮。
Rosetta為蘋(píng)果針對(duì)M1芯片推出的兼容模式
問(wèn)題5
- 執(zhí)行
pod trunk push SMSDK.podspec --allow-warnings - 報(bào)錯(cuò)
[!] Source code for your Pod was not accessible to CocoaPods Trunk. Is it a private repo or behind a username/password on http? - 解決
因?yàn)閜od是私有庫(kù),私有庫(kù)應(yīng)使用pod repo push而不是pod trunk push迄埃,浪費(fèi)不少時(shí)間,其實(shí)是因?yàn)楦沐e(cuò)了pod庫(kù)的模式兑障,創(chuàng)建pod私有庫(kù)其實(shí)毫無(wú)意義,但凡要給別人用流译,必須公開(kāi)。隱蔽源代碼應(yīng)該再創(chuàng)建個(gè)git倉(cāng)庫(kù)才對(duì)福澡,pod倉(cāng)庫(kù)只用來(lái)放編譯好的framework即可叠赦。
問(wèn)題6
- 執(zhí)行
pod package SMSDK.podspec --force --exclude-deps --no-mangle --embedded - 報(bào)錯(cuò)
fatal error:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: Pods/build/package.a and Pods/build-sim/package.a have the same architectures (arm64) and can't be in the same fat output file - 解決
其實(shí)還是和問(wèn)題1一樣革砸,錯(cuò)誤類型不同而已除秀,起初根本不知道什么原因算利,執(zhí)行pod package時(shí)錯(cuò)誤不能穩(wěn)定出現(xiàn)册踩,后來(lái)才發(fā)現(xiàn)是緩存問(wèn)題效拭,每次打包前要執(zhí)行pod cache clean -- all暂吉,另外執(zhí)行打包時(shí)需要從git倉(cāng)庫(kù)拉代碼缎患,默認(rèn)拉取main分支借笙,所以版本分支的代碼還要及時(shí)同步到main较锡。
---------------------測(cè)試運(yùn)行------------------------
問(wèn)題7
Undefined symbols for architecture arm64
framework拖入項(xiàng)目后业稼,所有引用文件對(duì)應(yīng)的.m文件均編譯失敗蚂蕴,
已經(jīng)被前面幾個(gè)問(wèn)題折磨的死去活來(lái)俯邓,第一眼看到architecture arm64 想當(dāng)然的以為又是指令集問(wèn)題,不斷的換電腦熔号、切分支、新建項(xiàng)目引镊、clean項(xiàng)目朦蕴、刪除緩存弟头、重新打包吩抓、修改配置赴恨、編譯下載疹娶,重試無(wú)數(shù)種方案的組合伦连,新舊問(wèn)題交織在一起亂作一團(tuán)雨饺,簡(jiǎn)直要崩潰惑淳。
中間間或能成功運(yùn)行幾次额港,以為問(wèn)題解決歧焦,萬(wàn)事大吉移斩,趕緊各種備份倚舀。然而一覺(jué)醒來(lái)問(wèn)題依舊叹哭,當(dāng)場(chǎng)崩潰痕貌,完全的摸不著脈絡(luò)风罩。三天三夜舵稠,業(yè)務(wù)代碼一句沒(méi)動(dòng)超升。
嘗試過(guò)放棄pod工具集,用蘋(píng)果最原始的方案重新開(kāi)始室琢,腳本打包,但找了幾個(gè)腳本根本不能良好運(yùn)行落追,再去debug太耗時(shí)間;還有只創(chuàng)建framework不創(chuàng)建demo,用編譯產(chǎn)物導(dǎo)入到其它項(xiàng)目運(yùn)行巢钓,也不能準(zhǔn)確生效。
還有一些零碎的問(wèn)題症汹,比如手動(dòng)拖入項(xiàng)目和從Link Binary With Libraies導(dǎo)入的具體區(qū)別;還有Genral tab下Embed的Do Not Embed ,Embed&Sign, Embed Without Signing三選項(xiàng)的區(qū)別和聯(lián)系背镇。
偶然在新項(xiàng)目里 用pod 導(dǎo)入了某第三方咬展,發(fā)現(xiàn)對(duì)應(yīng)的錯(cuò)誤消失瞒斩,想起之前項(xiàng)目里需要在Podflie和spec都導(dǎo)入pod破婆,忘了什么原因济瓢。
--------------重新回到pod package荠割。
- --exclude-deps 用于剔除第三方生成旺矾。
為作為服務(wù)方framework集成第三方后難免與主項(xiàng)目沖突,所以為了解決沖突打包時(shí)去掉了第三方依賴夺克,這也是為什么pod lint和pod package不報(bào)錯(cuò)的原因
- --no-mangle 用于避免pod新建命名空間
默認(rèn)的mangle用來(lái)提前命名類來(lái)避免沖突,第三方庫(kù)的類名前都會(huì)加入統(tǒng)一前綴铺纽,例如:PodYourPodName_YourClass,而且--no-mangle和 --exclude-deps 無(wú)法拆分使用狡门,當(dāng)剔除第三方生成時(shí) 陷寝,命名修改毫無(wú)意義其馏;不剔除第三方凤跑,不重新命名肯定沖突叛复。
問(wèn)題8
- 執(zhí)行
pod package SMSDK.podspec --force --embedded - 報(bào)錯(cuò)
[!] podspec has binary-only depedencies, mangling not possible. - 解決
因項(xiàng)目里使用了其它靜態(tài)文件仔引,無(wú)法打包成framework............卒褐奥。
重新使用 pod package SMSDK.podspec --force --exclude-deps --no-mangle --embedded 強(qiáng)制打包咖耘。
將測(cè)試項(xiàng)目?jī)?nèi)導(dǎo)入framework依賴的第三方后撬码,所有問(wèn)題解決儿倒。