如何获取我在config.xml中定义的版本字符串

时间:2015-02-03 16:41:35

标签: cordova version versioning

我如何找到我的Cordova应用程序的版本?我需要该信息才能在“关于”屏幕中显示。

是否可以读取config.xml并获取我已经在此文件中维护的版本字符串?

<widget ... version="0.0.1" ...

我想有一个解决方案,我不必在代码中的几个地方维护应用程序的版本号。此外,我不想为此目的插件,因为大多数插件不支持Android,iOS和浏览器作为平台。

或者我是否忽略了核心插件属性?

或者是否有一个解决方案,我维护一个文件,这不是config.xml,config.xml从该文件中获取版本信息?

您是如何在应用的屏幕上实现“显示版本信息”的?任何提示都表示赞赏。

我的Cordova版本是:

>cordova -v
4.2.0

7 个答案:

答案 0 :(得分:17)

如果您对使用任何第三方插件不感兴趣,那么我觉得Cordova钩子是要走的路。您可以使用before_build挂钩来读取config.xml文件中的版本,并在应用程序中使用相同的版本。

幸运的是,在以下link中,您可以随时使用此挂钩,它们从config.xml读取版本并在需要时将其作为依赖项注入。

建议您查看cordova hooks的官方文档,以便更好地理解。

实际上,您还可以尝试从config.xml中读取版本信息,并直接将其放在您可以在index.html中创建的占位符中以显示版本信息。这可以在使用钩子进行cordova构建之前完成,而钩子又使用执行文件操作的Windows批处理文件。您可以在我的github page中签出使用批处理文件的cordova钩子的工作样本。

答案 1 :(得分:5)

根据其他答案,我创建了以下before_prepare钩子,该钩子在cordova 9 / ionic 5中最适合我。

它不需要任何其他库来解析config xml,因为它是由regex获取版本的。 它可以在browseriOSandroid平台环境中工作。 同样,它在ionic serve中也不起作用,因为此处未执行cordova挂钩。

#!/usr/bin/env node
// Add %%VERSION%% at any place to index.html file to be replaced by this script.

var fs = require('fs');
var path = require('path');

function fileStringReplace(filename, search, replace) {
    var content = fs.readFileSync(filename, 'utf8');
    content = content.replace(new RegExp(search, "g"), replace);

    fs.writeFileSync(filename, content, 'utf8');
}

module.exports = function(context) {
    var rawConfig = fs.readFileSync("config.xml", 'ascii');
    var match = /^<widget.+version="([\d\.]+)".+?>$/gm.exec(rawConfig);

    if(!match || match.length != 2)
        throw new Error("version parse failed");

    var version = match[1];

    fileStringReplace("www/index.html", "%%VERSION%%", version);
    console.log("replaced version to " + version);
}

将以下挂钩注册添加到config.xml

<hook src="hooks/patch-indexhtml-version.js" type="before_prepare" />

index.html的作用:

<html lang="de" data-appversion="%%VERSION%%">

现在您可以执行以下操作以在您的应用中获取版本:

document.documentElement.getAttribute("data-appversion");

答案 2 :(得分:3)

基于@Gandhi在他的回答中指出的脚本,我更新了脚本以使其适用于我当前的cordova @ 8:我将它用作&#34; after_prepare & #34;挂钩,而不是&#34; before_build&#34;,就像在后一种情况下更改的文件在挂钩执行后 后很快将东西复制到平台目录时再次被覆盖... < / p>

该脚本使用xml2js,因此请务必执行npm i xml2js --save-dev以使xml2js可用。

#!/usr/bin/env node

// taken from https://www.bram.us/2015/01/04/cordova-build-hook-script-for-displaying-build-version-in-your-app/
// see https://stackoverflow.com/a/42650842
// This plugin replaces text in a file with the app version from config.xml.

// be sure to exec `npm i xml2js --save-dev` to make xml2js available


var wwwFileToReplace = "js/config.js";

var fs = require('fs');
var path = require('path');
var xml2js = require('xml2js');

function loadConfigXMLDoc(filePath) {
    var json = "";
    try {
        var fileData = fs.readFileSync(filePath, 'ascii');
        var parser = new xml2js.Parser();
        parser.parseString(fileData.substring(0, fileData.length), function (err, result) {
                           //console.log("config.xml as JSON", JSON.stringify(result, null, 2));
                           json = result;
                           });
        console.log("File '" + filePath + "' was successfully read.");
        return json;
    } catch (ex) {
        console.log(ex)
    }
}

function replace_string_in_file(filename, to_replace, replace_with) {
    var data = fs.readFileSync(filename, 'utf8');

    var result = data.replace(new RegExp(to_replace, "g"), replace_with);
    fs.writeFileSync(filename, result, 'utf8');
    //console.log("replaced in ", filename, "(", to_replace, " -> ", replace_with);
    var data2 = fs.readFileSync(filename, 'utf8');
    console.log(data2);
}

module.exports = function(context) {

    // var rootdir = process.argv[2]; // old cordova version
    var rootdir = context.opts.projectRoot;
    console.log("projectRoot=", rootdir);

    var configXMLPath = "config.xml";
    var rawJSON = loadConfigXMLDoc(configXMLPath);
    var version = rawJSON.widget.$.version;
    console.log("Version:", version);

    // var currentBuildPlatforms = process.env.CORDOVA_PLATFORMS.split(","); // old cordova version
    var currentBuildPlatforms = context.opts.cordova.platforms;
    //console.log(JSON.stringify(context));
    console.log("Current build platforms: ", currentBuildPlatforms);

    if (rootdir) {
        currentBuildPlatforms.forEach(function(val, index, array) {
            var wwwPath = "";
            switch(val) {
                case "ios":
                    wwwPath = "platforms/ios/www/";
                    break;
                case "android":
                    wwwPath = "platforms/android/assets/www/";
                    break;
                default:
                    console.log("Unknown build platform: " + val);
            }
            var fullfilename = path.join(rootdir, wwwPath + wwwFileToReplace);
            if (fs.existsSync(fullfilename)) {
                replace_string_in_file(fullfilename, "%%VERSION%%", version);
                console.log("Replaced version in file: " + fullfilename);
            }
        });
    }

}

config.xml

中加入此挂钩
<hook src="scripts/after_prepare_read_app_version.js" type="after_prepare" />

答案 3 :(得分:1)

我会做这样的事情:

cordova.getAppVersion.getVersionNumber().then(function (version) {
   if (!window.localStorage['version'] || window.localStorage['version'] <    version) {
       window.localStorage['version'] = version;
   }
});

通过这种方式,您可以在任何需要的地方拨打window.localStorage['version']

答案 4 :(得分:1)

我使用https://github.com/whiteoctober/cordova-plugin-app-version处描述的插件 第1步:cordova插件添加https://github.com/whiteoctober/cordova-plugin-app-version.git

2步(剪切和粘贴) 如果您使用的是jQuery或AngularJS,则支持promise样式。使用类似的东西:

cordova.getAppVersion.getVersionNumber().then(function (version) {
    $('.version').text(version);
});

如果没有,则传递一个回调函数:

cordova.getAppVersion.getVersionNumber(function (version) {

alert(version);
});

欢呼声

答案 5 :(得分:0)

我在 2020 年 12 月写作。现在最简单的解决方案是使用插件 cordova-plugin-app-version

<块引用>

从目标构建设置中读取您的应用版本 [来自 config.xml]

安装

cordova plugin add cordova-plugin-app-version

只需在您的 JS 中使用类似的东西:

cordova.getAppVersion.getVersionNumber(function (version) {
  console.log('APP version is ' + version)
  $('.version').text(version)
})

在您的 html 中,您可以使用它在任何您想要的位置插入版本:

<span class="version"></span>

答案 6 :(得分:0)

这里是我对不同答案的汇编。 我用它来更新 Xcode 项目中的一些参数以进行插件编译。

您可以看到我从 config.xml 中获取了应用程序 ID 和名称

您可以将其添加到 after_prepare 钩子中:

<hook src="scripts/addBuildSettingsToXcode.js" type="after_prepare" />

#!/usr/bin/env node

let fs    = require('fs');
let xcode = require('xcode');
let path = require('path');
let et = require('elementtree');


module.exports = function (context) {
    //console.log(context);

    function addBuildPropertyToDebugAndRelease(prop, value) {
        console.log('Xcode Adding   ' + prop + '=' + value);
        myProj.addBuildProperty(prop, value, 'Debug');
        myProj.addBuildProperty(prop, value, 'Release');
    }

    function updateBuildPropertyToDebugAndRelease(prop, value) {
        console.log('Xcode Updating ' + prop + '=' + value );
        myProj.updateBuildProperty(prop, value, 'Debug');
        myProj.updateBuildProperty(prop, value, 'Release');
    }


    // Getting app id and name from config.xml
    let config_xml = path.join(context.opts.projectRoot, 'config.xml');
    let data = fs.readFileSync(config_xml).toString();
    let etree = et.parse(data);
    let appId = etree.getroot().attrib.id ;
    let appName = etree.getroot().find('name')['text'];

    // Building project path
    let projectPath = 'platforms/ios/' + appName + '.xcodeproj/project.pbxproj';

    // Opening Xcode project and parsing it
    myProj = xcode.project(projectPath);
    myProj = myProj.parseSync();

    // Common properties
    addBuildPropertyToDebugAndRelease('DEVELOPMENT_TEAM', 'CGXXXXXXX');
    addBuildPropertyToDebugAndRelease('CODE_SIGN_IDENTITY', '"Apple Development"');

    // Compilation properties
    addBuildPropertyToDebugAndRelease('ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES', 'YES');

    // Save project file
    fs.writeFileSync(projectPath, myProj.writeSync());

};