首页 > 解决方案 > 如何在 NativeScript 的“before-prepare”-hook 中操作 projectIdentifiers/app 标识符

问题描述

有没有办法通过 NativeScript (6.3) 中的特定钩子 (例如 before-prepare) 更改/操作应用程序 ID ( com.somename.xyz )?

我们正在使用带有一些符号链接的白标签应用程序(来自同一代码库的多个客户端)来使用不同的 CSS 文件、字体等,并希望以编程方式更改包名称:

文件:/hooks/before-prepare/app-identifier.js

module.exports = function ($logger, $projectData, $injector, hookArgs) {
  return new Promise((resolve, reject) => {
    $projectData.projectIdentifiers.ios = 'com.somename.xyz'
    $projectData.projectIdentifiers.android = 'com.somename.xyz'
    resolve()
  })
}

...但应用程序开始于

“成功在设备模拟器上同步应用程序com.brand.abc ... ”

(在我们的 package.json 中定义)

标签: nativescript

解决方案


您可以在after-prepare挂钩中执行此操作 - 对于 Android 通过修改strings.xml文件和对于 iOS 通过编辑plist

var plist = require('simple-plist');
var path = require("path");
var fs = require("fs");

module.exports = function($logger, $projectData, hookArgs) {

    return new Promise(function(resolve, reject) {
        const platformFromHookArgs = hookArgs && (hookArgs.platform || (hookArgs.prepareData && hookArgs.prepareData.platform));
        const platform = (platformFromHookArgs  || '').toLowerCase();
        var env = (hookArgs.platformSpecificData || hookArgs.prepareData).env;
        if (platform === 'ios') {
            let infoFile = path.join($projectData.platformsDir, "ios", $projectData.projectName, $projectData.projectName + '-Info.plist');
            if (fs.existsSync(infoFile) && env && env.version ) {
                let parts = env.version.split('.');
                let data = plist.readFileSync(infoFile);
                if (env.environment && env.environment !== 'prod') {
                    data.CFBundleDisplayName = env.environment + ' - ' + data.CFBundleDisplayName
                }
                plist.writeFileSync(infoFile, data);
            }
        }
        if (platform === 'android') {
            infoFile = path.join($projectData.platformsDir, 'android','app', 'src', 'main', 'res','values', 'strings.xml');
            if (fs.existsSync(infoFile) && env && env.environment && env.environment !== 'prod')  {
                let contents = fs.readFileSync(infoFile,'utf8');
                contents = contents.replace(/MyNativeScriptAppName/g, env.environment + ' - MyNewEnvname');
                fs.writeFileSync(infoFile, contents);
            }                
        }
        resolve();
    });
}

请注意,以上假设环境变量已在tns build命令中设置。这可以通过使用DefinePluginwebpack 来完成:

// Define useful constants like TNS_WEBPACK
            new webpack.DefinePlugin({
                "global.TNS_WEBPACK": "true",
                "process.env": {
                    environment: (env && Object.prototype.hasOwnProperty.call(env, 'environment')) ? JSON.stringify(env.environment) : undefined
                },
            }),

推荐阅读