ถนนไกล
กรณีใช้ของฉันคือ:
- ฉันกำลังซิงโครไนซ์เวอร์ชันและสร้างหมายเลขในหลาย ๆ เป้าหมาย
- ฉันกำลังซิงโครไนซ์เวอร์ชันและสร้างหมายเลขกับเป้าหมาย
Settigns.bundle
- ฉันกำลังอ่านและแก้ไขหมายเลขบิลด์จากเซิร์ฟเวอร์ CI
ฉันเคยรันจุด 1 และ 2 เป็นสคริปต์สร้างเป้าหมายและจุด 3 เป็นสคริปต์ที่กำหนดเองใน CI เอง
วิธีใหม่ในการจัดเก็บเวอร์ชันและบิลด์ภายในการตั้งค่าการสร้าง Xcode ทำให้เกิดปัญหากับสคริปต์เนื่องจากไม่สามารถแก้ไขค่าได้อย่างมีประสิทธิภาพอีกต่อไป อย่างน้อยก็อ่านได้
น่าเสียดายที่ฉันไม่สามารถค้นพบวิธีที่ถูกต้องในการป้องกัน Xcode ไม่ให้จัดเก็บเวอร์ชันและหมายเลขบิลด์ลงในการตั้งค่าการสร้างโปรเจ็กต์อย่างไรก็ตามฉันได้จัดการเพื่อสร้างวิธีแก้ปัญหา
ปรากฎว่าเมื่อมีการสร้างหรือเก็บทำค่าเขียนในInfo.plist
ถูกนำมาใช้ ซึ่งหมายความว่าค่าจะถูกแทนที่ระหว่างเวลาบิลด์ซึ่งไม่อนุญาตให้เราแก้ไขในระหว่างเวลาบิลด์เดียวกัน
ฉันยังพยายามแก้ไขโครงการโดยใช้xcodeproj
CLI อย่างไรก็ตามการเปลี่ยนแปลงใด ๆ ในโครงการทำให้งานสร้างใด ๆ หยุดลงดังนั้นโซลูชันนี้ไม่ทำงาน
ในที่สุดหลังจากหลายวิธีที่ฉันลองใช้ในที่สุดฉันก็จัดการพบการประนีประนอมที่ไม่ได้ละเมิดพฤติกรรมใหม่ของ Xcode
คำตอบสั้น ๆ :
ในฐานะที่เป็นเป้าหมายของการดำเนินการล่วงหน้าสคริปต์จะถูกดำเนินการซึ่งจะเขียนค่าที่เกี่ยวข้องไปยังCFBundleShortVersionString
และCFBundleVersion
ไปยังเป้าหมายของInfo.plist
ในฐานะที่เป็นแหล่งความจริงฉันใช้การตั้งค่าการสร้าง Xcode เพื่ออ่านค่าMARKETING_VERSION
และCURRENT_PROJECT_VERSION
เป้าหมายที่ต้องการ
วิธีนี้เมื่อคุณปรับเปลี่ยนค่าจากการตั้งค่าโครงการ - ในบิลด์ถัดไป / การเก็บถาวร - ค่าเหล่านั้นจะถูกเขียนไปยังInfo.plist
อนุญาตให้ใดก็ได้หากตรรกะการเขียนสคริปต์ที่มีอยู่ของคุณยังคงทำงานต่อไป
คำตอบโดยละเอียด
วิธีเดียวที่จะแก้ไขทรัพยากรตามการดำเนินการสร้างคือการใช้pre-action
สคริปต์ หากคุณลองทำจากสคริปต์การสร้าง - การเปลี่ยนแปลงจะไม่มีผลทันทีและจะไม่ปรากฏในตอนท้ายของการสร้าง / เก็บถาวร
เพื่อที่จะเพิ่มการดำเนินการสร้างล่วงหน้า - ไปที่รูปแบบการแก้ไข
จากนั้นขยายส่วนสร้างและเก็บถาวร ภายใต้Pre-action
คลิกProvide build and settings from
ดร็อปดาวน์และเลือกแหล่งที่มาของเป้าหมายความจริงที่คุณต้องการอ่านค่า
เพิ่มสคริปต์ต่อไปนี้:
# 1)
cd ${PROJECT_DIR}
# 2)
exec > Pruvit-Int.prebuild.sync_project_version_and_build_with_info_plists.log 2>&1
# 3)
./sync_project_version_and_build_with_info_plists.sh $MARKETING_VERSION $CURRENT_PROJECT_VERSION
บรรทัด scrip ทำสิ่งต่อไปนี้:
- ไปที่ไดเรกทอรีที่มีสคริปต์การซิงค์อยู่เพื่อเรียกใช้งาน
- อนุญาตให้เขียนบันทึกในระหว่างการดำเนินการล่วงหน้าไม่เช่นนั้นเอาต์พุตใด ๆ จะถูกปิดเสียงโดยค่าเริ่มต้น
- ดำเนินการสคริปต์การซิงค์โดยระบุ
MARKETING_VERSION
และCURRENT_PROJECT_VERSION
ขั้นตอนสุดท้ายคือการเขียนสคริปต์ซิงค์ของคุณเองที่อ่านค่าของที่ให้ไว้MARKETING_VERSION
และCURRENT_PROJECT_VERSION
ไปยังเป้าหมาย / s ที่เกี่ยวข้องและเมื่อใดก็ตามที่คุณต้องการ
ในกรณีของฉันสคริปต์มีดังต่อไปนี้:
#!/bin/bash
#IMPORTANT - this script must run as pre-action of each target's Build and Archive actions
version_number=$1
build_number=$2
echo "version_number is $version_number"
echo "build_number is $build_number"
#update Pruvit/Info.plist
pruvitInfoPlist="Pruvit/Info.plist"
/usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $version_number" $pruvitInfoPlist
/usr/libexec/PlistBuddy -c "Set CFBundleVersion $build_number" $pruvitInfoPlist
#update Pruvit/Settings.bundle
settingsPlist="Pruvit/Settings.bundle/Root.plist"
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:0:DefaultValue $version_number" $settingsPlist
/usr/libexec/PlistBuddy -c "Set PreferenceSpecifiers:1:DefaultValue $build_number" $settingsPlist
#update BadgeCounter/Info.plist
badgeCounterInfoPlist="BadgeCounter/Info.plist"
/usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $version_number" $badgeCounterInfoPlist
/usr/libexec/PlistBuddy -c "Set CFBundleVersion $build_number" $badgeCounterInfoPlist
ฉันใช้การแชร์Info.plist
และSettings.bundle
ระหว่างเป้าหมายแอพทั้งสองของฉันดังนั้นฉันต้องอัปเดตครั้งเดียว
นอกจากนี้ฉันใช้ส่วนขยายบริการการแจ้งเตือนBadgeCounter
ซึ่งจะต้องมีรุ่นเดียวกันที่แน่นอนและสร้างเป็นเป้าหมายที่มันจะถูกฝัง ดังนั้นฉันจึงอัปเดตสิ่งนี้เช่นกัน