問題
升級(jí)Xcode12之后叉存,單測(cè)的target (ReadInJoyTests) 出現(xiàn)了報(bào)錯(cuò):
error: Cycle inside ReadInJoyTests; building could produce unreliable results.
Cycle details:
→ Target 'ReadInJoyTests': CodeSign /Users/yoferzhang/Library/Developer/Xcode/DerivedData/QQMSFContact-gpvqexdcrtvrsdczqfqownxrezqo/Build/Products/Debug-iphonesimulator/QQ.app/EarlGrey.framework
○ That command depends on command in Target 'ReadInJoyTests': script phase “[CP] Copy Pods Resources”
○ Target 'ReadInJoyTests': CodeSign /Users/yoferzhang/Library/Developer/Xcode/DerivedData/QQMSFContact-gpvqexdcrtvrsdczqfqownxrezqo/Build/Products/Debug-iphonesimulator/QQ.app/EarlGrey.framework
解決方案,是要?jiǎng)h除 ReadInJoyTests target 中 build phase 的 [CP] Copy Pods Resources 的 Output file lists
手動(dòng)刪除
手動(dòng)清空后蝶押,pod install
后還是會(huì)生成润讥。
腳本刪除
考慮是否可以通過腳本刪除呛梆。
刪除方法
腳本刪除可以分為以下幾步:
- 獲取主工程的
xcodeproj
- 找到target
ReadInJoyTests
target - 找到build phase
[CP] Copy Pods Resources
- 保存project
刪除的代碼
require 'xcodeproj'
def delete_rij_tests_output_file_lists
puts "===================> Start delete ReadInJoyTests Target [CP] Copy Pods Resources output file lists"
project_path = './QQMSFContact.xcodeproj'
project = Xcodeproj::Project.open(project_path)
project.targets.each do |target|
if target.name == "ReadInJoyTests"
puts "===================> Find ReadInJoyTests Target"
build_phase = target.build_phases.find { |bp| bp.display_name == '[CP] Copy Pods Resources' }
puts "===================> Before delete, Output file lists:"
puts build_phase.output_file_list_paths
# 執(zhí)行刪除
while build_phase.output_file_list_paths.length > 0
build_phase.output_file_list_paths.pop()
end
end
end
# 保存工程文件
project.save
puts "===================> Finish delete ReadInJoyTests Target [CP] Copy Pods Resources output file lists"
end
刪除時(shí)機(jī)
首先來看一下cocoapods的hook執(zhí)行順序
- 終端執(zhí)行命令
pod install
- 運(yùn)行
podfile
中的 ruby method - 執(zhí)行hook
pre_install
- 執(zhí)行 pod install 的行為吟税,但此時(shí)修改內(nèi)容還在內(nèi)存的 installer 中,還未寫入磁盤
- 執(zhí)行hook
post_install
稀轨,同上還是未寫入磁盤 - 將installer修改部分寫入磁盤
如果在 post_install
中執(zhí)行 delete_rij_tests_output_file_lists
扼脐,那因?yàn)?post_install
內(nèi)pod的修改還沒寫入磁盤,delete_rij_tests_output_file_lists 的修改靶端,會(huì)被 post_install
之后pod寫入磁盤而覆蓋掉谎势。導(dǎo)致刪除失敗凛膏。
調(diào)試發(fā)現(xiàn)杨名,如果在第3步之前, output file paths
內(nèi)容存在猖毫,則在post_install
中執(zhí)行刪除台谍,就不會(huì)發(fā)生覆蓋寫入時(shí)重新生成 output file paths
。
也就是說可以在第3步之前吁断,先通過腳本寫入 path趁蕊,欺騙cocoapods,path存在仔役,這次 install 就不要生成path 做添加動(dòng)作掷伙。然后在post_install
中執(zhí)行刪除邏輯,這樣就解決了問題又兵。
寫入path的代碼為:
def add_rij_tests_temp_output_file_list
project_path = './QQMSFContact.xcodeproj'
project = Xcodeproj::Project.open(project_path)
project.targets.each do |target|
if target.name == "ReadInJoyTests"
puts "===================> Find ReadInJoyTests Target"
build_phase = target.build_phases.find { |bp| bp.display_name == '[CP] Copy Pods Resources' }
puts "===================> Before add, temp output file lists:"
puts build_phase.output_file_list_paths
list_path = '${PODS_ROOT}/Target Support Files/Pods-ReadInJoyTests/Pods-ReadInJoyTests-resources-${CONFIGURATION}-output-files.xcfilelist'
# 添加路徑
if build_phase.output_file_list_paths.include?(list_path) == false
build_phase.output_file_list_paths.push(list_path)
end
end
end
# 保存工程文件
project.save
end
最后修改完成的podfile 為
# 省略上述兩個(gè)method定義
post_install do |installer|
# 省略...
# 刪除 ReadInJoyTests Target [CP] Copy Pods Resources output file lists
delete_rij_tests_output_file_lists
end
# pod install之前添加一次任柜,讓 pod 認(rèn)為已經(jīng)有了path,pod install過程中就不會(huì)再新增了
add_rij_tests_temp_output_file_list
完整流程
最后來看完整的流程
- 臨時(shí)添加
output file path
沛厨,讓cocoapods認(rèn)為本次install
無需做添加path的動(dòng)作宙地。 - install 生成工程修改(不會(huì)添加path)
-
post_install
中再刪除output file path
- pod將install 寫入磁盤。
See Also
最后提供一個(gè)不用 xcodeproj
工具的刪除方法
post_install do |installer|
installer.aggregate_targets.each do |target|
if target.name == "Pods-ReadInJoyTests"
puts "==========> Find Pods-ReadInJoyTests:"
project = target.user_project
puts project
project.targets.each do |sub_target|
if sub_target.name =="ReadInJoyTests"
puts "==========> Find ReadInJoyTests Target"
build_phase = sub_target.build_ phases. find { |bp| bp.display_name == '[CP] Copy Pods Resources' }
puts "==========> Before delete, Output file lists:"
puts build_phase.output_file_list_paths
#執(zhí)行刪除
build_phase.output_file_list_paths.pop( )
puts"==========> After delete, Output file lists:"
puts build_phase.output_file_list_paths
end
end
project. save
end
end
end