2010-09-16 93 views
22

顯然這個文件被緩存了,所以只有當它被修改時纔會生成。我有環境變量設置爲增加我的版本號,等等,並獨立於plist更新它們(實際上在項目構建設置中)。是否有腳本可以用作強制Info.plist更新的腳本構建階段?其他一些方便的方法?如何在每次構建項目時強制Xcode在我的項目中重建Info.plist文件?

+0

我有這個完全相同的問題。我試過觸摸它並將其添加爲構建腳本的輸出。只有Clean和Build才能刷新它。我已經開始賞金了。 – 2011-02-22 19:30:58

回答

11

選擇「編輯計劃」建立關於選項卡上,然後從左側的控件中選擇「Build」。

rm "${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}" 

這將刪除:

然後,添加一個預操作步驟,確保有問題的方案下拉了「從提供構建設置」,然後添加到下面的編輯窗口,這是選擇緩存版本Info.plist,導致XCode在您每次構建時重建它。

+0

不要忘記引號:rm「$ {CONFIGURATION_BUILD_DIR}/$ {INFOPLIST_PATH}」 – 2014-02-07 20:29:20

+0

謝謝 - 我已經更新了答案 – LeeH 2014-02-08 15:26:00

+3

它在xCode 8.2中不再有效。1 – hsafarya 2016-12-29 13:50:07

12

您可以嘗試使用touch命令來更新時間戳,我認爲這是Xcode用來確定是否應該重建的時間戳。

$ touch Info.plist 
+1

我試過從Xcode裏面觸摸,但它什麼也沒做。實際上對Info.plist進行更改是實現更新的唯一方法。我會嘗試從命令行看看它是否有效 – TraxusIV 2010-09-16 21:31:12

+0

好吧,只需「觸摸Info.plist」就可以添加Run Script構建階段,它會在構建時自動更新,但僅限於其他構建。 – TraxusIV 2010-09-16 21:36:05

+0

運行腳本構建步驟是第一個執行? – bosmacs 2010-09-17 13:53:40

1

有目標的獲取信息窗口的「生成」選項卡的選項,跌幅在標有「預處理Info.plist文件」,你可以檢查「包裝」。我相信會更新每個版本的文件。

+0

nope,no-go。它也導致了錯誤,因爲我的版權字符串中有一個URL,並且c預處理器顯然不知道如何處理http://中的//。 – TraxusIV 2010-09-16 21:30:00

9

執行此操作的一種方法是創建Run Script構建階段,以從Info.plist.template文件生成Info.plist,然後在創建包之後生成rm Info.plist。來自評論Dave DeLong的想法發表在他的博客here

如果它的緩存非常嚴重(即,即使您沒有在文件歷史記錄中打開Info.plist,也要進行緩存),您也可以在此腳本中使用rm緩存版本。

+0

謝謝你來拯救我。這似乎是完美的。 – 2011-03-01 18:50:51

0

確保你也刷新你的plist視圖。
在Xcode中查看plist時,只需單擊plist中根元素旁邊的顯示三角形(Information Property List)。然後再次單擊以展開它。
您會看到值已刷新。我正在運行一個類似的腳本,並認爲它只是間歇性地工作,直到我意識到plist視圖根本不令人耳目一新。

5

在Xcode 4中,您可以使用預生成操作來觸摸信息plist。

注意:這與運行腳本構建階段不同。在Xcode檢查信息plist之前發生預生成操作,在Xcode已經檢查信息plist(這是爲什麼它每隔一次只能工作)之後似乎發生了運行腳本生成階段。

  1. 去編輯方案>生成>預動作
  2. 點擊「+」按鈕,選擇「新建運行腳本行動」
  3. 選擇你的目標在下拉列表
  4. 了「從提供構建設置」
  5. 在腳本框中添加touch "${SRCROOT}/${INFOPLIST_FILE}"
+1

此預構建操作不適用於我。它仍然以某種方式「緩存」Info.plist。例如如果我做了一個乾淨的構建(不管這個建議),並使用PlistBuddy從源appTarget-Info.plist或build-dir/Info.plist中提取版本信息,我就能得到我所期望的,但如果我改變了項目中的版本信息在重新構建之前沒有進行清理,我得到舊值...即使執行手動PlistBuddy -c打印顯示上述兩個文件都具有我想要的新值。 – 2012-11-27 22:50:05

0

另一種方法是創建僅具有構建階段的「聚合」目標。用它來觸摸Info.plist文件。使該目標成爲構建應用的目標的依賴關係。

因爲它是一個獨立的目標和你的應用程序目標的依賴關係,所以它會在你的應用程序目標的Info.plist文件被檢查之前建立。 (如別處所述,在Info.plist文件的修改時間已被檢查後,應用目標本身的構建階段發生得太遲。)

13

我也自動設置了我的版本號。我創建了一個運行腳本構建階段。 關鍵是要更新Info.plist的目標生成目錄副本不能建立目錄 一。您還需要在複製捆綁階段之後擁有您的運行腳本。可以直接編輯0​​包文件,因爲在代碼簽名之前。你不想生成重新發明輪子的文件。

這裏是我的腳本:

# ---------------------------- IMPORTANT ---------------------------- 
# You must set GITHash to something like 'Set by build script' in the file 
# file '<Project Name>-Info.plist' in the 'Supporting Files' group 
# ------------------------------------------------------------------- 
# 
# Get the version number from the tag in git and the number of commits as the build number 
# 
appVersion=$(git describe --long | cut -f 1 -d "-") 
appBuild=$(git describe --long | cut -f 2 -d "-") 
gitHash=$(git describe --long | cut -f 3 -d "-") 
echo "From GIT Version = $appVersion Build = $appBuild" 

# 
# Set the version info in plist file 
# 
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $appVersion" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}" 
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $appBuild" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}" 
/usr/libexec/PlistBuddy -c "Set :GITHash $gitHash" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}" 
echo "Updated ${TARGET_BUILD_DIR}/${INFOPLIST_PATH}" 

僅供參考我還自動設置版本,並用下面的代碼

NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; 
NSString *appDisplayName = infoDictionary[@"CFBundleDisplayName"]; 
NSString *majorVersion = infoDictionary[@"CFBundleShortVersionString"]; 
NSString *minorVersion = infoDictionary[@"CFBundleVersion"]; 

self.appDescription.text = [NSString stringWithFormat:@"Dirty Dog Software\n%@\nVersion: %@(%@)", 
         appDisplayName, majorVersion, minorVersion];       
0

對於那些一直在努力實現自動版本控制的項目,我創建了一個macOS GitHub project,演示如何以非常簡單直接的方式實現它,這要感謝@GayleDDS和Daniel Farrelly及其博客的想法版本控制和我自己的一些實現。我認爲你可以毫無麻煩地將它翻譯成其他平臺上的項目。

這裏有一個關於如何將它複製到項目中的小指南(Xcode 8)。

  1. 爲了減少發生這種錯誤的機率,請確保您已預先將所有目標添加到您的項目中。
  2. 轉到菜單文件>新建文件...,然後向下滾動,然後選擇配置設置文件
  3. 將它命名爲BuildNumber,不要忘了這個配置文件添加到你想要的所有目標保持同步; CURRENT_PROJECT_VERSION = 1:保存該文件
  4. 你應該可以看到一個名爲BuildNumber.xcconfig在您的項目顯示
  5. 添加到該文件下面的文字前,通過點擊相應的複選框,這樣做。如果你願意,你可以從另一個號碼開始。這將會是你的內部版本號,每次構建時都會增加。 請不要更改變量的名稱,儘管
  6. 如果你有一個以上的目標,添加下面的腳本由導航建項目第一目標>目標>構建階段
  7. 導航到菜單編輯>添加構建階段>添加運行腳本階段
  8. A 運行腳本階段應該已經添加到您的目標;所以拖動它直到目標依賴關係(這個細節很重要!)。
  9. 現在到了有趣的部分,我將線幾乎行解釋腳本:

開始在腳本的第一行創建於PlistBuddy路徑:

plistbuddy="/usr/libexec/PlistBuddy" 

添加行2讀取配置文件,然後讀取5.

OLD_VERSION=`cat "$SRCROOT/BuildNumber.xcconfig" | awk '/CURRENT_PROJECT_VERSION/ { print $3 }'` 

3-11線路設置NEW_VERSION與被撞開您在步驟設置了CURRENT_PROJECT_VERSION變量然後用新的內部版本號保存配置文件;其餘線路的營銷版本和內部版本號保存到的plist:

NEW_VERSION=`cat "$SRCROOT/BuildNumber.xcconfig" | awk '/CURRENT_PROJECT_VERSION/ { print $3 + 1 }'` 
sed -i '' "s/CURRENT_PROJECT_VERSION = .*/CURRENT_PROJECT_VERSION = $NEW_VERSION/" "$SRCROOT/BuildNumber.xcconfig" 
CURRENT_PROJECT_VERSION=$NEW_VERSION 
BUILD_STR="Build $NEW_VERSION" 
COPYRIGHT_STR="© 2017 MyCompany.net" 
APP_VERSION_STR="1.3.5" 
$plistbuddy -c "Set :CFBundleShortVersionString $APP_VERSION_STR" "${SRCROOT}/$TARGETNAME/Info.plist" 
$plistbuddy -c "Set :CFBundleVersion $BUILD_STR" "${SRCROOT}/$EXECUTABLE_NAME/Info.plist" 
$plistbuddy -c "Set :NSHumanReadableCopyright $COPYRIGHT_STR" "$INFOPLIST_FILE" 

我還顯示,8-11行如何使用Xcode中設置其腳本不同的環境變量。您可以添加額外的行來編輯其他目標的info.plist,然後保持主應用程序和助手的版本同步。去GitHub,下載該項目並使用它,然後適應您的需求。使用Xcode進行快速自動版本控制。

0

和Xcode 8.3.2

由@LeeH答案從2013年開始我已經提出了兩種解決方案對我來說,重建的Info.plist啓發工作。

解決方案1:最簡單,最優雅的

最簡單的辦法是強制的Xcode通過讀您的自定義變量觸摸你的目標Info.plist

添加構建階段,見下面的截圖(原爲screenshotted解決),以及剛加入這一行:

touch $INFOPLIST_FILE 

這就是全部!現在Xcode應該強制將自定義變量重新加載到Info.plist文件中。

此解決方案與@lukelutman建議的相同,但使用Build階段。預執行腳本不適用於我。

解決方案2:更復雜和哈克

另一種解決方案是刪除在build目錄的緩存Info.plist

我寫了這個超級簡單的小bash腳本

#!/bin/bash 
info_plist="$CONFIGURATION_BUILD_DIR/$PRODUCT_NAME.app/Info.plist" 
echo "Removing Info.plist from build dir in order to force rebuild of it and reading of correct xcconfig variables, plist path $info_plist" 
rm "$info_plist" 

然後我救了它,並把它稱爲從目標構建階段。我把它作爲第一個構建階段。

enter image description here

背景:

我有三種配置:ConfigAlphaAppStore和我使用的通用連接,推送通知和其他工作人員需要使用的應享權利的文件。但我不想擁有三個授權文件,每個配置文件一個。

我的項目已經非常依賴配置文件(.xcconfig)。我實際上使用自定義配置變量設置了授權文件(MyAppsProductName.entitlements)。

但我想讀取相同的配置變量運行時,我想我可以做到這一點,如果他們將被添加到我的目標Info.plist。哪些工作!

但我注意到,當我更改了我的.xcconfig文件中的值時,Info.plist文件沒有更改值。我注意到,如果我執行了乾淨的構建,則Info.plist中的值根據.xcconfig文件中的值得到更新。 Xcode確實緩存了Info.plist文件。

所以上面的這些解決方案解決了這個問題。希望能幫助到你! :)

討論

我如果解決方案2有任何優勢解決方案1 ​​ ...可能不是沒有想法?任何人輸入?

相關問題