通过Cordova config.xml将条目添加到iOS .plist文件


80

我是Cordova CLI的新手。

我需要通过Cordova以编程方式执行以下步骤。

  1. 在项目.plist中添加新行
  2. 在新行中输入以下值:
  3. 密钥:GDLibraryMode类型:字符串(默认):GDEnterpriseSimulation

我想我需要在项目根目录下的config.xml文件中执行此操作(或者也许在“ platforms”文件夹中的目录中)。

有人可以向我解释如何通过config.xml添加条目,以便在编译时添加上述条目吗?

我正在使用Cordova 3.3.1-0.42(我知道它不是最新的)。我已经完成了我的项目,一切都很好,我只需要将此条目添加到pList中即可。


4
对于任何迟到的人,Cordova CLI 7及更高版本现在都支持在项目plist中设置值。
18:02宣布

Answers:


67

我认为您无法通过直接config.xml修改来做到这一点。至少,在文档中我没有看到任何提及:http : //cordova.apache.org/docs/en/3.3.0/config_ref_index.md.html

我认为您必须创建一个插件,因为它们可以插入plist条目:http : //docs.phonegap.com/en/3.3.0/plugin_ref_spec.md.html#Plugin%20Specification

请参阅“配置文件元素”部分。这是有关该部分相关部分的猜测plugin.xml

<platform name="ios">
<config-file target="*-Info.plist" parent="CFBundleURLTypes">
<array>
    <dict>
        <key>GDLibraryMode</key>
        <string>GDEnterpriseSimulation</string>
    </dict>
</array>
</config-file>
</platform>

然后,您可以安装插件: cordova plugin add <your plugin name or file location>


1
@mooreds对不起,我错过了您的答案...我认为您的解决方案正在使用gap:config-file。现在,我了解了您的方法(为特定的plist修改创建专用的插件),我将尝试一下。谢谢!
Fafaman

6
@ mooreds,Cordova / PhoneGap文档具有误导性。我发现应该在中指定键parent,而值部分应该是内部XML。在这种特定情况下,应如下所示:<config-file target =“ *-Info.plist” parent =“ GDLibraryMode”> <string> GDEnterpriseSimulation </ string> </ config-file>
Herman Kan


1
谢谢@rjhilgefort,非常简单!:)
josebailo 2015年

2
作为参考,从Cordova CLI 7+开始,可以config.xmlvia<config-file>元素中完成此操作-有关其他操作的详细信息,请参见其他答案。
18:16宣布

43

我真的很喜欢使用Cordova钩子的@james解决方案。但是,有两个问题。该文档说明:

  • “我们强烈建议您使用Node.js编写钩子”
  • /hooks目录被认为已被弃用,而有利于config.xml

这是使用plist NPM包的Node.js实现:

var fs    = require('fs');     // nodejs.org/api/fs.html
var plist = require('plist');  // www.npmjs.com/package/plist

var FILEPATH = 'platforms/ios/.../...-Info.plist';

module.exports = function (context) {

    var xml = fs.readFileSync(FILEPATH, 'utf8');
    var obj = plist.parse(xml);

    obj.GDLibraryMode = 'GDEnterpriseSimulation';

    xml = plist.build(obj);
    fs.writeFileSync(FILEPATH, xml, { encoding: 'utf8' });

};

在Cordova提供的所有挂钩类型中,与您的情况有关的挂钩类型为:

  • after_prepare
  • before_compile

选择一个挂钩类型,然后将挂钩添加到您的config.xml文件中:

<platform name="ios">
    <hook type="after_prepare" src="scripts/my-hook.js" />
</platform>

节点plist库在解析我的plist文件时遇到一些问题,因此我无法使用此解决方案,而是选择了James',后者使用了Mac附带的PListBuddy可执行文件。如果仅plist库更可靠,那么这是一个很好的解决方案。我确实config.xml按照您的建议从文件中引用了我的脚本。
stephen.hanson's

真好!无需使用任何其他插件,并且就像一个魅力!对于这样一个简单的问题,所有其他解决方案似乎都已过时或变得复杂。
亚诺·范·奥尔特

plist npm模块严重损坏。当源文件包含空值时,它将生成无效的.plist文件。请改用simple-plist。
cleong

我在使用cordova @ 8添加本地插件时遇到了很多麻烦,这种解决方案在我的情况下效果更好并且更简单
Jean-Baptiste Martin

32

您可以在Cordova钩子脚本中使用PlistBuddy实用程序来修改* -Info.plist文件。

例如,我有以下脚本,在<project-root>/hooks/after_prepare/010_modify_plist.sh该脚本下添加了一个字典属性,并在该字典中添加了一个条目:

#!/bin/bash

PLIST=platforms/ios/*/*-Info.plist

cat << EOF |
Add :NSAppTransportSecurity dict
Add :NSAppTransportSecurity:NSAllowsArbitraryLoads bool YES
EOF
while read line
do
    /usr/libexec/PlistBuddy -c "$line" $PLIST
done

true

确保使脚本可执行(chmod +x)。

true在脚本的结束是因为PlistBuddy一个错误退出代码返回如果该键被添加已经存在,并且不提供一种方法来检测,如果该键已经存在。如果挂钩脚本以错误状态退出,则Cordova将报告生成错误。更好的错误处理是可能的,但实现起来很麻烦。


有用!我尝试了您和TachyonVortex的解决方案。TachyonVortex解决方案使用的node.js库无法正确解析我的PList文件,而答案中使用的包含Mac的PListBuddy可以正确解析。我确实引用了config.xmlTachyonVortex推荐的钩子。
stephen.hanson 16/09/28

1
如果您想每次都更新plist,即使该键已经存在,则Remove : NSAppTransportSecurity 在add语句之前添加,它将首先删除NSAppTransportSecurity,然后添加它。这不应该使任何崩溃。
塞缪尔·汤普森

22

这些是我最终要做的步骤,使我的应用程序可以通过iTunes在设备之间共享文件。

1.在您的应用程序中,导航到config.xml。在platform标记下的配置中键入此段 <platform name="ios">

 <config-file platform="ios" target="*-Info.plist" parent="UIFileSharingEnabled">
      <true/>
  </config-file>

2.然后转到命令行工具并键入:cordova prepare

  1. 在设备上卸载并重新安装应用程序,您将看到您的应用程序出现在iTunes中,您可以在设备之间共享任何文件。

有几件事,请确保cordova是最新的,并且您已为ios添加了平台。

npm install -g cordova

此命令将安装cordova。

cordova platform add ios

此命令为ios添加平台。

发生的事情是,当您运行cordova prepare命令时,您正在使用在platform / ios文件夹中生成的Apple Xcode SDK。在此处,您可以看到为应用程序生成的plist文件,该文件标记为“ yourApp-info.plist”。在这里,您可以看到在xml布局中生成的新键和字符串,如下所示:

 <key>UIFileSharingEnabled</key>
 <true/>

同样值得警告的是,我的公司在几周前(期限很短)将该离子框架应用程序丢到了我的腿上。我告诉您的一切都是基于数周的学习。因此,这可能不是最佳做法,但我希望它可以帮助某人。

编辑

链接到文档


4
要进行此操作,还需要其他任何方法吗?我正在使用Cordova 6.2(最新生产),即使我将条目添加到config.xml中,我也没有在plist中看到它。您是否可能有Cordova Custom Config插件(github.com/dpa99c/cordova-custom-config)?
Tomer Cagan

1
奇迹般有效。谢谢。
Logus

<config-file>元素是在Cordova CLI版本7中添加的,因此在Cordova CLI的最新版本中可以使用(请参见此github问题,以了解cordova-custom-config的作者提供的可复制的证明)。
18:02宣布

这对我有用!但是,将平台指定为标签上的属性似乎是多余的,尤其是因为它已经放置在iOS平台下。没有我的工作。
Eric F.

14

现在,使用config.xml似乎可以实现:至少一些核心插件作者这样说。例如,在Cordova Camera Plugin的文档中,他们讨论了iOS 10中的新要求,即您在plist中提供了权限消息字符串。为此,他们建议执行带有参数的plugin add命令,从而:

cordova plugin add cordova-plugin-camera --variable CAMERA_USAGE_DESCRIPTION="My App would like to access your camera, to take photos of your documents."

结果是您不仅将新的<plugin>添加到config.xml中,而且还包含一个<variable>子级:

<plugin name="cordova-plugin-camera" spec="~2.3.0">
    <variable name="CAMERA_USAGE_DESCRIPTION" value="My App would like to access your camera, to take photos of your documents." />
</plugin>

哪一个似乎与info.plist中的新键相关联,也许以某种方式在运行时传递值?

  <key>NSCameraUsageDescription</key>
  <string/>
  <key>NSPhotoLibraryUsageDescription</key>
  <string/>

如果我说我完全知道它是如何工作的,那我会撒谎,但这似乎指明了道路。


CAMERA_USAGE_DESCRIPTION传递给NSCameraUsageDescription。如果要为NSPhotoLibraryUsageDescription添加值,则还需要添加<variable name="PHOTOLIBRARY_USAGE_DESCRIPTION" value="whatever" />
Nico Westerdale

1
如果您使用的是PhoneGap Build服务,则这是设置这些值的推荐方法
Nico Westerdale

我必须<string>Random camera usage text</string>在密钥下方添加一个选项<key>NSCameraUsageDescription</key>,才能接受我的构建。该配置未添加文字
Slartibartfast

9

更新:对于要在iOS> = 10上使用相机的人。这意味着,通常,您可以在插件中配置为:

 <!-- ios -->
 <platform name="ios">

     <config-file target="*-Info.plist" parent="NSLocationWhenInUseUsageDescription">
         <string></string>
     </config-file>
     <config-file target="*-Info.plist" parent="NSCameraUsageDescription">
         <string></string>
     </config-file>
      <config-file target="*-Info.plist" parent="NSPhotoLibraryUsageDescription">
         <string></string>
     </config-file>

 </platform>

但现在,你不能配置NSCameraUsageDescriptionNSPhotoLibraryUsageDescription在插件。您需要通过Xcode在平台-> iOS项目中或在*-Info.plist文件中对其进行配置。

从iOS 10开始,必须在info.plist中添加NSCameraUsageDescription和NSPhotoLibraryUsageDescription。

了解更多:https//www.npmjs.com/package/cordova-plugin-camera


8

我在ionic 3中使用了以下内容,而没有任何其他插件或导入,我认为这可能对其他人有帮助:

<platform name="ios">
    <edit-config file="*-Info.plist" mode="merge" target="NSLocationWhenInUseUsageDescription">
        <string>Location is required so we can show you your nearby projects to support.</string>
    </edit-config>
    <edit-config file="*-Info.plist" mode="merge" target="NSCameraUsageDescription">
        <string>Camera accesss required in order to let you select profile picture from camera.</string>
    </edit-config>
    <edit-config file="*-Info.plist" mode="merge" target="NSPhotoLibraryUsageDescription">
        <string>Photo library accesss required in order to let you select profile picture from gallery / library.</string>
    </edit-config>
</platform>

4

您可以通过直接在plugins目录中编辑ios.json来在应用程序的plist中设置显示名称。

将以下内容添加到ios.json文件的config_munge.files部分中即可达到目的,并且即使使用CLI也会维护该内容。

"*-Info.plist": {

    "parents": {
        "CFBundleDisplayName": [
            {
                "xml": "<string>RevMob Ads Cordova Plugin Demo</string>",
                "count": 1
            }
        ]
    }
}

这是一个完整的例子


1
请注意,当从Visual Sutdio Tools for Cordova运行时,这不起作用,因为ios.json被该工具覆盖。
Herman Kan 2015年

2
这个答案有两个问题。首先,/plugins/ios.json运行时,对的所有手动编辑都将丢失,cordova platform remove ios其次是cordova platform add ios。其次,@ Red2678要求一种解决方案“通过Cordova以编程方式执行编辑……以便在编译时添加新条目”。
TachyonVortex

3

@TachyonVortex解决方案似乎是最好的选择,但在我的情况下却崩溃了。此问题是由空的NSMainNibFile字段引起的,该字段未由plist NPM软件包正确转换。在.plist文件中

    <key>NSMainNibFile</key>
    <string></string>
    <key>NSMainNibFile~ipad</key>
    <string></string>

转换为:

    <key>NSMainNibFile</key>
    <string>NSMainNibFile~ipad</string>

我通过添加到脚本来修复它:

    obj.NSMainNibFile = '';
    obj['NSMainNibFile~ipad'] = '';

脚本最终看起来像(scripts / my-hook.js):

var fs    = require('fs');     // nodejs.org/api/fs.html
var plist = require('plist');  // www.npmjs.com/package/plist

var FILEPATH = 'platforms/ios/***/***-Info.plist';

module.exports = function (context) {

    var xml = fs.readFileSync(FILEPATH, 'utf8');
    var obj = plist.parse(xml);

    obj.GDLibraryMode = 'GDEnterpriseSimulation';
    obj.NSMainNibFile = '';
    obj['NSMainNibFile~ipad'] = '';

    xml = plist.build(obj);
    fs.writeFileSync(FILEPATH, xml, { encoding: 'utf8' });

};

和config.xml:

<platform name="ios">
    <hook type="before_build" src="scripts/my-hook.js" />
</platform>

patch_plist.jshooks/after_platform_add目录中用此代码编写了一个。但是我仍然进入<key>NSMainNibFile</key><string>NSMainNibFile~ipad</string>我的plist文件。有什么想法可以解决这个问题吗?
罗曼·


2

是的,有可能!

我正在使用Cordova 9.0.0(cordova-lib@9.0.1)。

例如,这是我用来将新的字符串值插入Info.plist的配置文件:

<platform name="ios">
    <edit-config file="*-Info.plist" mode="merge" target="NSMicrophoneUsageDescription">
        <string>My awesome app wish to hear your awesome voice through Microphone. Not for fancy stuff, just want to hear you.</string>
    </edit-config>
    <edit-config file="*-Info.plist" mode="merge" target="---Key configuration---">
        <string>---string value---</string>
    </edit-config>
</platform>

之后,不要忘记通过在终端中运行以下两个命令来重建登台文件:

cordova platform rm ios
cordova platform add ios

要确认更改,可以通过使用xCode打开新生成的.plist文件来检查它们。

-Info.plist文件位于:

./platform/ios/[your app name]/[your app name]-Info.plist

edit-config假设目标已经存在于您的plist中。只是要清楚一点,如果您想添加一个新的键/字符串对,则应该config-file改用,这会将新的子级添加到xml树中
Daniel Lizik 19-10-24

0

如果您尝试.plist在带有<config-file>标记的本机iOS插件中修改plugin.xml,则需要执行以下操作:

  1. 确保您.plist是xml,而不是二进制!您可以plutil用来将二进制文件.plist转换为xml,并将其提交给版本控制。

    plutil -convert xml1 Info.plist

  2. 对于这些指令<config-file>表明target=相对于在生成的Xcode项目platforms/ios/<project>/,但我发现我需要一个通配符预先考虑到我的路径,得到它的工作:

    target="*/Resources/MyResources.bundle/Info.plist"

  3. 如果您想在最顶层添加密钥 .plist需要将parent设置为与密钥名称相同,然后嵌套<string>带有该值的标签。使用<array><dict>作为任何示例所示,将导致这些键嵌套在下 parent

这是一个适用于我的完整示例,用于添加多个顶级属性:

<platform name="ios">
    <config-file target="*/Resources/MyResources.bundle/Info.plist" parent="MyDistribution">
        <string>Cordova</string>
    </config-file>
    <config-file target="*/Resources/MyResources.bundle/Info.plist" parent="MyVersion">
        <string>3.2.0</string>
    </config-file>
</platform>

这对我没有用。我尝试添加上面的内容,但列表中没有任何变化
Samuel Thompson

尝试通过首先将plist放在根目录中来缩小原因范围?不幸的是,据我所知,该功能无声地失败了。
Sky Kelsey

0

对于较大的项目,或者如果您有多个使用相同权限的插件,我更喜欢after_prepare挂钩。但您始终可以采用以下简单方法:

只需:-删除需要所需权限的插件-使用--save再次添加-在config.xml中,该插件现在有了一个带有空白说明的新变量,您可以填写-现在用-release和ios构建他们将被设置。



-4

您只需要执行以下步骤1。

转到项目导航器中选择目标单击从选项卡选择其他选项的信息,是构建设置构建阶段,你会看到键类型值当你点上的任意键的名称,你会发现+和- +号写的标志点击Key: GDLibraryMode的关键部分 Type:StringValue:GDEnterpriseSimulation价值部分中的tyoe 部分


1
我完全想这样做,但是当我从CLI编译Cordova应用程序时,项目的文件夹基本上被删除并重新制作。然后,我每次编译时都必须执行上述操作(不是那样很难),但是我希望仅使用Cordova的config.xml来为我执行此操作。
Red2678

您能告诉我为什么要通过xcode来运行应用程序的原因,然后这种解决方案才是您需要的吗?
Nitin 2014年

2
@Nitin,您好:嗯,这不是“要求”,而是使用Cordova CLI的标准方法。如果我使用“命令Cordova构建”,则每次运行该命令时,项目文件夹都会被删除并重新制作。
Red2678 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.