Xcode 基于 JSON 配置文件构建动态设置版本
Xcode build dynamically set version based off JSON config file
N.B。这是一个 React Native 项目。
使用 Android 和 Gradle,我能够解析 JSON 文件并读取值以在构建期间将版本动态应用到应用程序。
JSON 文件看起来像这样:
{
"name": "AwesomeApp",
"displayName": "Awesome",
"version": {
"major": 3,
"minor": 2,
"patch": 1
}
}
最简单的形式,Gradle 文件有这样的:
def jsonFile = file('../../app.json')
def parsedJson = new groovy.json.JsonSlurper().parseText(jsonFile.text)
def versionMajor = parsedJson.version.major
def versionMinor = parsedJson.version.minor
def versionPatch = parsedJson.version.patch
def appVersionCode = versionMajor * 10000 + versionMinor * 100 + versionPatch
def appVersionName = "${versionMajor}.${versionMinor}.${versionPatch}"
然后在构建中,我可以将其设置为使用动态设置的版本:
android {
compileSdkVersion 26
buildToolsVersion '26.0.1'
defaultConfig {
applicationId "com.awesome.app"
...
versionCode appVersionCode
versionName appVersionName
...
}
}
如何使用 iOS 和 Xcode 实现同样的效果?我知道我们需要修改 CFBundleShortVersionString
和 Build Phases 似乎是动态设置版本的最佳方式,但是这些似乎都是增量的/ [=41 的一部分=] 某种工具,而不是读取明确设置的 JSON 文件。
如有任何帮助,我们将不胜感激。
(N.B。如果我遗漏了任何会导致否决票的明显内容,请告诉我,我可以相应地修改问题 - 大量点击否定并不能真正帮助提出有效问题的发帖人-> 抱歉,这是基于我之前问过的一个问题。
最后通过我在 Xcode 构建阶段的 运行 脚本中调用的 Node 脚本完成了此操作:
构建阶段脚本:
AppVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}")
APP_VERSION="$AppVersion" node ${PROJECT_DIR}/../iOSVersioning.js
iOSVersioning.js:
const { exec } = require('child_process');
const APP_VERSION = process.env.APP_VERSION;
const version = require('../app.json').version;
const versionName = `${version.major}.${version.minor}.${version.patch}`;
if (APP_VERSION == versionName) {
process.exit();
}
exec(
`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${versionName}" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"`,
(err, stdout, stderr) => {
if (err) {
console.log('Failed to apply the app version.');
process.exit(1);
}
console.log(`Applied app verion: ${versionName}`);
}
);
N.B。这是一个 React Native 项目。
使用 Android 和 Gradle,我能够解析 JSON 文件并读取值以在构建期间将版本动态应用到应用程序。
JSON 文件看起来像这样:
{
"name": "AwesomeApp",
"displayName": "Awesome",
"version": {
"major": 3,
"minor": 2,
"patch": 1
}
}
最简单的形式,Gradle 文件有这样的:
def jsonFile = file('../../app.json')
def parsedJson = new groovy.json.JsonSlurper().parseText(jsonFile.text)
def versionMajor = parsedJson.version.major
def versionMinor = parsedJson.version.minor
def versionPatch = parsedJson.version.patch
def appVersionCode = versionMajor * 10000 + versionMinor * 100 + versionPatch
def appVersionName = "${versionMajor}.${versionMinor}.${versionPatch}"
然后在构建中,我可以将其设置为使用动态设置的版本:
android {
compileSdkVersion 26
buildToolsVersion '26.0.1'
defaultConfig {
applicationId "com.awesome.app"
...
versionCode appVersionCode
versionName appVersionName
...
}
}
如何使用 iOS 和 Xcode 实现同样的效果?我知道我们需要修改 CFBundleShortVersionString
和 Build Phases 似乎是动态设置版本的最佳方式,但是这些似乎都是增量的/ [=41 的一部分=] 某种工具,而不是读取明确设置的 JSON 文件。
如有任何帮助,我们将不胜感激。
(N.B。如果我遗漏了任何会导致否决票的明显内容,请告诉我,我可以相应地修改问题 - 大量点击否定并不能真正帮助提出有效问题的发帖人-> 抱歉,这是基于我之前问过的一个问题。
最后通过我在 Xcode 构建阶段的 运行 脚本中调用的 Node 脚本完成了此操作:
构建阶段脚本:
AppVersion=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}")
APP_VERSION="$AppVersion" node ${PROJECT_DIR}/../iOSVersioning.js
iOSVersioning.js:
const { exec } = require('child_process');
const APP_VERSION = process.env.APP_VERSION;
const version = require('../app.json').version;
const versionName = `${version.major}.${version.minor}.${version.patch}`;
if (APP_VERSION == versionName) {
process.exit();
}
exec(
`/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${versionName}" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"`,
(err, stdout, stderr) => {
if (err) {
console.log('Failed to apply the app version.');
process.exit(1);
}
console.log(`Applied app verion: ${versionName}`);
}
);