Làm cách nào để ngăn Xcode 11 thay đổi CFBundleVersion và CFBundleShortVersionString thành $ (CURRENT_PROJECT_VERSION) và $ (MARKETING_VERSION)?


14

Kể từ phiên bản 11, Xcode đặt CFBundleVersiongiá trị của tôi thành $(CURRENT_PROJECT_VERSION)CFBundleShortVersionStringgiá trị của $(MARKETING_VERSION)tôi bất cứ khi nào tôi nhập giá trị Phiên bản hoặc Xây dựng trong cài đặt đích (tab "Chung").

Phiên bản thực tế và giá trị xây dựng mà tôi nhập hiện được lưu trữ trong tệp project.pbxproj. Tôi không muốn hoặc không thích hành vi này, vì tôi sử dụng các tập lệnh shell để sửa đổi các giá trị tại thời gian xây dựng.

Tôi có thể tự đặt các giá trị chính xác trong tệp Info.plist, nhưng ngay sau khi tôi thay đổi số Phiên bản hoặc Số bản dựng trong cài đặt đích, tệp Info.plist sẽ được thay đổi lại bằng Xcode.

Làm cách nào để ngăn Xcode 11 thực hiện việc này?

Khi tôi sửa đổi tập lệnh xây dựng của mình để tự thay đổi tệp dự án, Xcode sẽ ngay lập tức hủy bản dựng ngay khi tệp dự án được thay đổi.


Tại sao bạn muốn Xcode 11 ngừng thực hiện việc này, thay vì sửa đổi tập lệnh shell của bạn để lấy giá trị?
Manuel

1
@Manuel Tôi nghĩ rằng sửa đổi một plist bằng cách sử dụng plistbuddylà tốt và sạch sẽ, trong khi sửa đổi tệp dự án thì lộn xộn hơn, không đáng tin cậy và dễ bị thay đổi trong định dạng tệp.
Ông Zystem

1
Thao tác với tệp project.pbxproj không lộn xộn khi bạn hiểu định dạng tệp. Nó chỉ là một phong cách tiếp theo được ghi chép lại. Bạn thậm chí có thể sửa đổi các tập tin với plistbuddy, nó tương thích với định dạng này.
Manuel

Tôi đã cập nhật câu trả lời của tôi với một gợi ý cho trường hợp sử dụng của bạn.
Manuel

Câu trả lời:


1

Con đường rất xa

Trường hợp sử dụng của tôi là:

  1. Tôi đang đồng bộ hóa phiên bản và xây dựng số trên một số mục tiêu.
  2. Tôi đang đồng bộ hóa phiên bản và xây dựng số với mục tiêu Settigns.bundle
  3. Tôi đang đọc và sửa đổi số bản dựng từ máy chủ CI.

Tôi đã từng thực hiện điểm 1 và 2 dưới dạng tập lệnh xây dựng mục tiêu và điểm 3 dưới dạng tập lệnh tùy chỉnh trên chính CI.

Cách lưu trữ phiên bản và bản dựng mới trong cài đặt bản dựng Xcode đã gây ra sự cố với tập lệnh, vì chúng không còn có thể sửa đổi hiệu quả các giá trị. Ít nhất là đọc là có thể.

Thật không may, tôi không thể khám phá ra một cách hợp pháp để ngăn Xcode lưu trữ phiên bản và xây dựng số vào cài đặt xây dựng dự án, tuy nhiên tôi đã quản lý để tạo một cách giải quyết.

Nó chỉ ra rằng khi xây dựng hoặc lưu trữ được thực hiện, giá trị được ghi trong đó Info.plistđược sử dụng. Điều này có nghĩa là giá trị được thay thế trong thời gian xây dựng, điều này không cho phép chúng tôi sửa đổi nó trong cùng thời gian xây dựng.

Tôi cũng đã cố gắng sửa đổi dự án bằng xcodeprojcli, tuy nhiên mọi thay đổi đối với dự án đều khiến bất kỳ bản dựng nào bị dừng, vì vậy giải pháp này không hoạt động.

Cuối cùng, sau rất nhiều cách tiếp cận khác nhau mà tôi đã thử, cuối cùng tôi cũng đã tìm được một sự thỏa hiệp không vi phạm hành vi mới của Xcode.

Câu trả lời ngắn:

Là một hành động trước mục tiêu, một tập lệnh được thực thi để ghi các giá trị tương ứng đến CFBundleShortVersionStringCFBundleVersioncho mục tiêuInfo.plist

Là một nguồn sự thật, tôi sử dụng cài đặt xây dựng Xcode để đọc các giá trị của MARKETING_VERSIONCURRENT_PROJECT_VERSIONcủa mục tiêu mong muốn.

Bằng cách này, khi bạn sửa đổi các giá trị từ cài đặt dự án - khi xây dựng / lưu trữ tiếp theo - chúng sẽ được ghi vào Info.plist, cho phép bất kỳ nếu logic kịch bản hiện tại của bạn tiếp tục hoạt động.

Trả lời chi tiết

Cách duy nhất để sửa đổi tài nguyên theo hành động xây dựng là sử dụng pre-actiontập lệnh. Nếu bạn thử thực hiện nó từ tập lệnh xây dựng - các thay đổi sẽ không có hiệu lực ngay lập tức và sẽ không có mặt ở cuối quá trình xây dựng / lưu trữ.

Để thêm một hành động xây dựng trước - đi đến chỉnh sửa sơ đồ.

nhập mô tả hình ảnh ở đây

Sau đó mở rộng phần Xây dựng và Lưu trữ. Bên dưới Pre-action, nhấp vào Provide build and settings frommenu thả xuống và chọn nguồn đích đích mà bạn muốn đọc các giá trị.

nhập mô tả hình ảnh ở đây

Thêm đoạn mã sau:

# 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

Các dòng scrip làm như sau:

  1. Chuyển đến thư mục chứa tập lệnh đồng bộ hóa để thực thi nó
  2. Cho phép ghi nhật ký trong quá trình trước hành động, nếu không, mọi đầu ra đều bị tắt theo mặc định
  3. Thực thi tập lệnh đồng bộ hóa bằng cách cung cấp MARKETING_VERSIONCURRENT_PROJECT_VERSION

Bước cuối cùng là viết tập lệnh đồng bộ của riêng bạn để đọc các giá trị được cung cấp MARKETING_VERSIONCURRENT_PROJECT_VERSIONcho các mục tiêu / s tương ứng và bất cứ khi nào bạn muốn.

Trong trường hợp của tôi, kịch bản như sau:

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

Tôi sử dụng chia sẻ Info.plistSettings.bundlegiữa cả hai mục tiêu ứng dụng của mình, vì vậy tôi phải cập nhật điều này một lần.

Ngoài ra tôi sử dụng một tiện ích mở rộng dịch vụ thông báo BadgeCounter, phải có cùng một phiên bản và xây dựng làm mục tiêu mà nó được nhúng vào. Vì vậy, tôi cập nhật điều này là tốt.


1

Đừng.

Có lẽ có một lý do tại sao hành vi này thay đổi. Nếu các tính năng Xcode sau này được xây dựng dựa trên hành vi này, mọi thứ sẽ ngày càng được "xây dựng" xuống dòng.

Thay vì cố gắng uốn cong Xcode, hãy thay đổi cách tập lệnh xây dựng lấy các giá trị này:

Cách đọc phiên bản ứng dụng hiện tại trong Xcode 11 với tập lệnh

Nếu bạn cần thao tác với project.pbxprojtập tin, thì đó là một plist kiểu tiếp theo được ghi lại rõ ràng. Bạn có thể sử dụng plistbuddytương thích với định dạng cũ này. Bạn cũng có thể sử dụng awkvới nhiều kịch bản hơn nếu bạn có các thao tác phức tạp hơn.

Nếu tôi hiểu trường hợp sử dụng của bạn, bạn có thể viết một tập lệnh lấy số phiên bản cao nhất awkvà sau đó cập nhật tất cả các số phiên bản thấp hơn mà nó có thể tìm thấy trong tệp sed.


in các giá trị PlistBuddy dường như hoạt động tốt, nhưng khi tôi sử dụng setlệnh, toàn bộ project.pbxproj được chuyển đổi thành tệp .plist XML và không thể đọc được bằng Xcode. ví dụ:PlistBuddy -c "Set :objects:$configurationId:buildSettings:CURRENT_PROJECT_VERSION $newProjectVersion" "$projectFile"
Ông Zystem

Tùy thuộc vào chính xác những gì bạn muốn đạt được, bạn có thể phải sử dụng kết hợp các công cụ
Manuel

Khởi động lại Xcode đã khắc phục sự cố XML. Als nhận thấy rằng khi chạy tập lệnh xây dựng thay đổi pbxprojtập tin sẽ hủy bỏ bản dựng. Vì vậy, điều này không thực sự đi làm tôi sợ.
Ông Zystem

Tôi đã cập nhật câu hỏi ban đầu của tôi với thông tin trên.
Ông Zystem

1
Ví dụ: trường hợp sử dụng của tôi là đồng bộ hóa phiên bản và xây dựng trên nhiều mục tiêu - tôi muốn đặt phiên bản và xây dựng cho mục tiêu đầu tiên và điều đó sẽ được cập nhật tự động cho tất cả các mục tiêu khác. Nó đã hoạt động tốt trước đây, bởi vì bạn chỉ cần sửa đổi một tài nguyên. Bây giờ tôi không thể sửa đổi dự án trong giai đoạn xây dựng của bất kỳ mục tiêu nào, vì bản dựng bị hủy.
KoCMoHaBTa
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.