Xcode 11'in CFBundleVersion ve CFBundleShortVersionString değerlerini $ (CURRENT_PROJECT_VERSION) ve $ (MARKETING_VERSION) olarak değiştirmesini nasıl durdurabilirim?


14

Sürümü 11 beri Xcode benim setleri CFBundleVersiondeğer $(CURRENT_PROJECT_VERSION)ve benim CFBundleShortVersionStringdeğere $(MARKETING_VERSION)ben hedef ayarları (sekme "Genel") içinde Sürümü veya Yapı değerlerini girin her.

Girdiğim gerçek sürüm ve derleme değerleri artık project.pbxproj dosyasında saklanıyor. Ben istemek veya buildtime değerlerini değiştirmek için kabuk komut dosyaları kullandığım gibi, bu davranışı sevmiyorum.

Info.plist dosyasında doğru değerleri el ile ayarlayabilirim, ancak hedef ayarlarda Sürüm veya Derleme numaralarını değiştirir değiştirmez, Info.plist dosyası Xcode tarafından yeniden değiştirilir.

Xcode 11'in bunu yapmasını nasıl durdurabilirim?

Proje dosyasını değiştirmek için derleme komut dosyamı değiştirdiğimde, Xcode proje dosyası değiştirilir değişmez derhal derlemeyi iptal eder.


Değeri almak için kabuk betiğinizi değiştirmek yerine neden Xcode 11'in bunu durdurmasını istiyorsunuz?
Manuel

1
@Manuel Bence bir plist kullanarak değiştirmek plistbuddygüzel ve temiz, proje dosyasını değiştirmek çok daha dağınık, güvenilmez ve dosya biçiminde beklenmedik değişikliklere eğilimli olduğunu düşünüyorum.
Bay Zystem

1
Dosya biçimini anladığınızda project.pbxproj dosyasını değiştirmek dağınık değildir. Bu sadece iyi belgelenmiş bir Sonraki stil plist. Dosyayı plistbuddy ile bile değiştirebilirsiniz, bu formatla uyumludur.
Manuel

Yanıtımı kullanım durumunuz için bir öneri ile güncelledim.
Manuel

Yanıtlar:


1

Şimdiye kadar yol

Benim kullanım durumum şuydu:

  1. Sürümü senkronize ediyorum ve çeşitli hedefler arasında sayılar oluşturuyorum.
  2. Sürümü senkronize ediyorum ve sayıları hedefin Settigns.bundle
  3. Bir CI sunucusundan yapı numarasını okuyup değiştiriyorum.

Nokta 1 ve 2'yi hedef oluşturma komut dosyası ve nokta 3'ü CI üzerinde özel bir komut dosyası olarak yürütürdüm.

Sürümü ve yapıyı Xcode derleme ayarları içinde depolamanın yeni yolu, komut dosyalarını sorunlara neden oluyordu çünkü artık değerleri etkin bir şekilde değiştiremediler. En azından okuma mümkün oldu.

Ne yazık ki Xcode sürümünü saklamak ve proje oluşturma ayarlarına numaraları oluşturmak önleme yasal bir yol bulmak mümkün değildi, ancak ben bir geçici çözüm oluşturmak başardık.

Bir derleme veya arşiv yapıldığında, içinde yazılan değerin Info.plistkullanıldığı ortaya çıkıyor. Bu, değerin derleme süresi boyunca değiştirildiği anlamına gelir, bu da aynı derleme süresi boyunca değiştirmemize izin vermez.

Ayrıca xcodeprojcli kullanarak projeyi değiştirmeye çalıştım , ancak projede yapılan herhangi bir değişiklik herhangi bir derlemenin durmasına neden oluyordu, bu yüzden bu çözüm işe yaramadı.

Sonunda, denediğim birçok farklı yaklaşımdan sonra, sonunda Xcode'un yeni davranışını ihlal etmeyen bir uzlaşma bulmayı başardım.

Kısa cevap:

Bir hedef-eylem öncesi gibi, bir komut dosyası için ilgili değerleri yazar hangi yürütülür CFBundleShortVersionStringve CFBundleVersionhedef giden tarihiyleInfo.plist

Gerçeğin bir kaynağı olarak, istenen hedefin MARKETING_VERSIONve değerlerinin değerlerini okumak için Xcode derleme ayarlarını kullanıyorum CURRENT_PROJECT_VERSION.

Bu şekilde, değerleri proje ayarlarından değiştirdiğinizde - bir sonraki derleme / arşiv üzerine - Info.plistvarolan komut dosyası mantığınız çalışmaya devam ederse, buna yazılır .

Detaylı cevap

Derleme eylemi sırasında bir kaynağı değiştirmenin tek yolu bir pre-actionkomut dosyası kullanmaktır . Bir derleme komut dosyasından yapmayı denerseniz - değişiklikler hemen geçerli olmaz ve derleme / arşivin sonunda mevcut olmaz.

Bir derleme öncesi eylem eklemek için - şemayı düzenleme bölümüne gidin.

resim açıklamasını buraya girin

Ardından Oluştur ve Arşivle bölümlerini genişletin. Altında Pre-action, Provide build and settings fromaçılır menüyü tıklayın ve değerleri okumak istediğiniz doğruluk hedefinin kaynağını seçin.

resim açıklamasını buraya girin

Aşağıdaki komut dosyasını ekleyin:

# 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

Komut dosyası satırları aşağıdakileri yapar:

  1. Yürütmek için senkronizasyon komut dosyasının bulunduğu dizine gidin
  2. Ön eylem sırasında bir günlüğün yazılmasına izin verir, aksi takdirde tüm çıktılar varsayılan olarak susturulur
  3. Sağlayarak senkronizasyon komut yürütme MARKETING_VERSIONveCURRENT_PROJECT_VERSION

Son adım, sağlanan değerleri MARKETING_VERSIONve CURRENT_PROJECT_VERSIONilgili hedef (ler) i ve istediğiniz zaman okuyan kendi senkronizasyon komut dosyanızı yazmaktır .

Benim durumumda senaryo aşağıdaki gibidir:

#!/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

Ben paylaşılan Info.plistve Settings.bundleher iki uygulama hedefleri arasında kullanın , bu yüzden bu bir kez güncellemek zorunda.

Ayrıca BadgeCounter, tam olarak aynı sürüme sahip olması ve gömülü olduğu hedef olarak oluşturması gereken bir bildirim hizmeti uzantısı kullanıyorum . Bu yüzden ben de güncelleyin.


1

Yapma.

Muhtemelen bu davranışın değişmesinin bir nedeni vardır. Daha sonra Xcode özellikleri bu davranış üzerine inşa edilirse, işler daha fazla "inşa" satır aşağı.

Xcode'u bükmeye çalışmak yerine, derleme betiğinin bu değerleri nasıl alacağını değiştirin:

Xcode 11'deki mevcut uygulama sürümü komut dosyası ile nasıl okunur

project.pbxprojDosyayı manipüle etmeniz gerekiyorsa , iyi belgelenmiş bir Sonraki stil plistidir. plistbuddyBu eski formatla uyumlu olanı kullanabilirsiniz . awkDaha karmaşık manipülasyonlarınız varsa daha fazla komut dosyası ile de kullanabilirsiniz .

Kullanım durumunuzu anlarsam, en yüksek sürüm numaralarını alan bir komut dosyası yazabilir awkve ardından dosyada bulabileceği tüm düşük sürüm numaralarını güncelleyebilirsiniz sed.


değerlerin yazdırılması PlistBuddy iyi çalışıyor gibi görünüyor, ancak setkomutu kullandığımda tüm project.pbxproj bir XML .plist dosyasına dönüştürülür ve artık Xcode tarafından okunamaz. örnek:PlistBuddy -c "Set :objects:$configurationId:buildSettings:CURRENT_PROJECT_VERSION $newProjectVersion" "$projectFile"
Bay Zystem,

Tam olarak ne elde etmek istediğinize bağlı olarak, bir takım araçlar kullanmak zorunda kalabilirsiniz
Manuel

Xcode'u yeniden başlatmak XML sorununu çözdü. Als, pbxprojdosyayı değiştiren bir derleme komut dosyası çalıştırırken derlemeyi iptal edeceğini buldu . Yani bu gerçekten işe yaramayacak, korkuyorum.
Bay Zystem

Orijinal sorumu yukarıdaki bilgilerle güncelledim.
Bay Zystem

1
Örneğin - benim kullanım durumum sürümü senkronize etmek ve birden çok hedef arasında inşa etmek - ben sürümünü ayarlamak ve ilk hedefe inşa etmek istiyorum ve bu otomatik olarak diğer tüm güncellenir. Daha önce iyi çalışıyordu çünkü sadece bir kaynağı değiştiriyorsunuz. Şimdi herhangi bir hedefin oluşturma aşamasında projeyi değiştiremiyorum çünkü derleme iptal ediliyor.
KoCMoHaBTa
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.