Thêm mục nhập vào tệp .plist iOS qua Cordova config.xml


80

Tôi mới sử dụng Cordova CLI.

Tôi cần thực hiện các bước sau theo chương trình thông qua Cordova.

  1. Trong dự án .plist thêm một hàng mới
  2. Nhập các giá trị sau vào hàng mới:
  3. Khóa : GDLibraryMode Type : String (mặc định) Giá trị : GDEnterpriseSimulation

Tôi nghĩ rằng tôi cần thực hiện việc này trong tệp config.xml trong thư mục gốc của dự án của tôi (hoặc có thể là tệp trong thư mục "platform").

Ai đó có thể giải thích cho tôi cách thêm mục nhập qua config.xml để mục nhập trên được thêm vào lúc biên dịch không?

Tôi đang sử dụng Cordova 3.3.1-0.42 (tôi biết nó không phải là phiên bản mới nhất). Tôi đã thực hiện dự án của mình và tất cả đều ổn, tôi chỉ cần thêm mục nhập này được thêm vào pList.


4
Đối với bất kỳ ai đến muộn, việc cài đặt giá trị trong khay dự án hiện được hỗ trợ bởi Cordova CLI 7 trở lên .
decates

Câu trả lời:


67

Tôi không nghĩ rằng bạn có thể làm điều này thông qua config.xmlsửa đổi trực tiếp . Ít nhất, tôi không thấy bất kỳ đề cập nào về vấn đề này trong tài liệu: http://cordova.apache.org/docs/en/3.3.0/config_ref_index.md.html

Tôi nghĩ bạn phải tạo một plugin vì chúng có thể chèn các mục nhập plist: http://docs.phonegap.com/en/3.3.0/plugin_ref_spec.md.html#Plugin%20Specification

Xem phần 'phần tử tệp cấu hình'. Dưới đây là phỏng đoán phần liên quan của di plugin.xmlchúc trông như thế nào:

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

Sau đó, bạn có thể cài đặt plugin: cordova plugin add <your plugin name or file location>


1
@mooreds xin lỗi, tôi hiểu nhầm câu trả lời của bạn ... Tôi nghĩ rằng giải pháp của bạn đang sử dụng gap: config-file . Bây giờ, tôi đã hiểu cách tiếp cận của bạn (tạo một plugin chuyên dụng cho các sửa đổi plist cụ thể), tôi sẽ thử. Cảm ơn!
Fafaman

6
@mooreds, tài liệu Cordova / PhoneGap gây hiểu lầm. Tôi phát hiện ra rằng khóa phải được chỉ định trong parent, trong khi phần giá trị phải là XML bên trong. Trong trường hợp cụ thể này, nó sẽ như sau: <config-file target = "* - Info.plist" parent = "GDLibraryMode"> <string> GDEnterpriseSimulation </string> </config-file>
Herman Kan

4
Plugin này hoạt động tuyệt vời github.com/leecrossley/cordova-plugin-transport-security
rjhilgefort

1
Cảm ơn @rjhilgefort, dễ dàng hơn rất nhiều! :)
josebailo

2
Để tham khảo, kể từ Cordova CLI 7+, nó có thể được thực hiện trong phần tử config.xmlthông qua <config-file>- xem các câu trả lời khác để biết chi tiết về cách thực hiện điều đó.
decates

43

Tôi thực sự thích giải pháp của @ james bằng cách sử dụng móc Cordova. Tuy nhiên, có hai vấn đề. Các tài liệu nêu:

  • "chúng tôi thực sự khuyên bạn nên viết hook của mình bằng Node.js "
  • " /hooksthư mục được coi là không dùng nữa vì các phần tử hook trong config.xml"

Đây là một triển khai Node.js bằng cách sử dụng gói NPM plist :

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' });

};

Trong số tất cả các loại móc do Cordova cung cấp, những loại phù hợp với tình huống của bạn là:

  • after_prepare
  • before_compile

Chọn một loại hook, sau đó thêm hook vào config.xmltệp của bạn :

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

plistThư viện nút gặp một số vấn đề khi phân tích cú pháp tệp plist của tôi, vì vậy tôi không thể sử dụng giải pháp này và đã sử dụng James ', sử dụng tệp thực thi PListBuddy, được bao gồm trên máy Mac. Đây là một giải pháp tốt, giá như plistthư viện đáng tin cậy hơn. Tôi đã tham chiếu tập lệnh của mình từ config.xmltệp như bạn đề xuất.
stephen.hanson

Đẹp! Không cần sử dụng bất kỳ plugin bổ sung nào và hoạt động như một sự quyến rũ! Tất cả các giải pháp khác dường như đã lỗi thời hoặc trở nên phức tạp cho một vấn đề đơn giản như vậy.
Arno van Oordt

Mô-đun plist npm bị hỏng nghiêm trọng. Nó sẽ tạo ra tệp .plist không hợp lệ khi tệp nguồn chứa các giá trị trống. Thay vào đó, hãy sử dụng simple-plist.
cleong

Tôi đã có rất nhiều rắc rối thêm một plugin địa phương với cordova @ 8, giải pháp này hoạt động tốt hơn nhiều trong trường hợp của tôi và là đơn giản
Jean-Baptiste Martin

32

Bạn có thể sử dụng tiện ích PlistBuddy bên trong tập lệnh hook Cordova để sửa đổi tệp * -Info.plist.

Ví dụ: tôi có tập lệnh sau, trong <project-root>/hooks/after_prepare/010_modify_plist.shđó thêm thuộc tính từ điển và thêm mục nhập trong từ điển đó:

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

Đảm bảo thực thi tập lệnh ( chmod +x).

truecuối tập lệnh là vì PlistBuddytrả về với mã thoát lỗi nếu khóa được thêm vào đã tồn tại và không cung cấp cách phát hiện xem khóa đã tồn tại hay chưa. Cordova sẽ báo lỗi bản dựng nếu tập lệnh hook thoát với trạng thái lỗi. Có thể xử lý lỗi tốt hơn nhưng khó thực hiện.


Nó hoạt động! Tôi đã thử cả giải pháp của bạn và TachyonVortex. Thư viện node.js mà giải pháp của TachyonVortex sử dụng không phân tích cú pháp chính xác tệp PList của tôi, trong khi PListBuddy có trong máy Mac được sử dụng trong câu trả lời của bạn thì có. config.xmlMặc dù vậy, tôi đã tham khảo hook từ TachyonVortex.
stephen.hanson

1
Nếu bạn muốn LUÔN cập nhật plist mọi lúc ngay cả khi khóa đã tồn tại thì hãy thêm Remove : NSAppTransportSecurity ngay trước câu lệnh add và trước tiên nó sẽ xóa NSAppTransportSecurity sau đó thêm nó vào. Điều này sẽ không sụp đổ bất cứ điều gì.
Samuel Thompson.

22

Đây là các bước tôi đã thực hiện để cho phép ứng dụng của mình chia sẻ tệp qua itunes giữa các thiết bị.

1. trong ứng dụng của bạn, điều hướng đến config.xml của bạn. Nhập phần này vào cấu hình của bạn trong thẻ nền tảng <platform name="ios">.

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

2. Sau đó vào công cụ dòng lệnh của bạn và gõ: cordova chuẩn bị

  1. Gỡ cài đặt và cài đặt lại ứng dụng của bạn trên thiết bị của bạn và bạn sẽ thấy ứng dụng của mình xuất hiện trong itunes để bạn chia sẻ bất kỳ tệp nào giữa các thiết bị của mình.

Một vài điều, hãy đảm bảo rằng cordova được cập nhật và bạn đã thêm nền tảng cho ios.

npm install -g cordova

Lệnh này cài đặt cordova.

cordova platform add ios

Lệnh này thêm nền tảng cho ios.

Điều gì đang xảy ra là khi bạn chạy lệnh chuẩn bị cordova, bạn đang sử dụng SDK Xcode của Apple được tạo trong thư mục platform / ios. Ở đó, bạn có thể thấy tệp plist được tạo cho ứng dụng của mình, được gắn nhãn là "yourApp-info.plist". Ở đó, bạn có thể thấy khóa và chuỗi mới được tạo trong bố cục xml trông giống như sau:

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

Ngoài ra, lời cảnh báo, công ty của tôi đã bỏ ứng dụng khuôn khổ ion này vào lòng tôi một vài tuần trước (với thời hạn thực sự ngắn). Mọi thứ tôi đang nói với bạn đều dựa trên vài tuần học hỏi. Vì vậy, đây có thể không phải là cách thực hành tốt nhất, nhưng tôi hy vọng nó sẽ giúp ích cho ai đó.

Biên tập

Liên kết đến tài liệu


4
Có cần bất cứ điều gì khác để làm việc này không? Tôi đang sử dụng Cordova 6.2 (sản xuất mới nhất) và mặc dù tôi đã thêm mục nhập vào config.xml nhưng tôi không thấy nó trong danh sách. Có thể bạn có plugin Cordova Custom Config ( github.com/dpa99c/cordova-custom-config ) không?
Tomer Cagan

1
Hoạt động như một sự quyến rũ. Cảm ơn.
Logus

Phần <config-file>tử đã được thêm vào phiên bản Cordova CLI 7, vì vậy với phiên bản gần đây của Cordova CLI, phần tử này sẽ hoạt động (xem vấn đề github này để biết bằng chứng có thể tái tạo từ tác giả của cordova-custom-config ).
Decates

Điều này đã làm việc cho tôi! Tuy nhiên, việc chỉ định nền tảng làm thuộc tính trên thẻ có vẻ thừa, đặc biệt là vì nó đã được đặt dưới nền tảng iOS. Nó hoạt động mà không có điều đó trên của tôi.
Eric F.

14

Điều này dường như có thể thực hiện được bây giờ bằng cách sử dụng config.xml: ít nhất một số tác giả plugin cốt lõi nói như vậy. Ví dụ: trong tài liệu dành cho Plugin máy ảnh Cordova , họ thảo luận về yêu cầu mới trong iOS 10 mà bạn cung cấp chuỗi thông báo quyền trong danh sách. Để thực hiện nó, họ đề xuất thực hiện lệnh add plugin với các đối số, do đó:

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

Điều này dẫn đến kết quả là bạn không chỉ nhận được một <plugin>tệp mới được thêm vào config.xml mà còn có một phần tử <variable>con:

<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>

Sau đó, cái nào dường như tương quan với các khóa mới trong info.plist của tôi, có lẽ bằng cách nào đó chuyển các giá trị trong thời gian chạy?

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

Tôi sẽ nói dối nếu tôi nói rằng tôi biết chính xác nó hoạt động như thế nào, nhưng nó có vẻ chỉ đường.


CAMERA_USAGE_DESCRIPTION được chuyển tới NSCameraUsageDescription. Nếu bạn muốn thêm một giá trị cho NSPhotoLibraryUsageDescription bạn cũng cần phải thêm<variable name="PHOTOLIBRARY_USAGE_DESCRIPTION" value="whatever" />
Nico Westerdale

1
Nếu bạn đang sử dụng các dịch vụ xây dựng PhoneGap đây là cách đề nghị để thiết lập những giá trị
Nico Westerdale

Tôi đã phải thêm một <string>Random camera usage text</string>khóa bên dưới <key>NSCameraUsageDescription</key>để bản dựng của tôi được chấp nhận. Cấu hình không thêm văn bản
Slartibartfast

9

CẬP NHẬT: dành cho những người muốn sử dụng máy ảnh với iOS> = 10. Điều này có nghĩa là, thông thường bạn có thể cấu hình trong plugin như:

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

Nhưng hiện tại, bạn không thể cấu hình NSCameraUsageDescriptionNSPhotoLibraryUsageDescriptiontrong plugin. Bạn cần định cấu hình chúng trong nền tảng -> dự án iOS bằng Xcode hoặc trong *-Info.plisttệp.

Kể từ iOS 10, bắt buộc phải thêm NSCameraUsageDescription và NSPhotoLibraryUsageDescription vào info.plist.

Tìm hiểu thêm: https://www.npmjs.com/package/cordova-plugin-camera


8

Tôi đang sử dụng phần sau trong ionic 3 mà không có bất kỳ plugin hoặc nhập bổ sung nào và tôi nghĩ điều này có thể hữu ích cho những người khác:

<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

Bạn có thể đặt tên hiển thị trong danh sách ứng dụng bằng cách chỉnh sửa trực tiếp ios.json trong thư mục plugin.

Thêm phần sau vào phần config_munge.files của tệp ios.json sẽ thực hiện thủ thuật và nó sẽ được duy trì ngay cả khi sử dụng CLI.

"*-Info.plist": {

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

Đây là một ví dụ hoàn chỉnh


1
Lưu ý rằng điều này không hoạt động khi chạy từ Công cụ Visual Sutdio cho Cordova, vì ios.json bị ghi đè bởi các công cụ.
Herman Kan

2
Có hai vấn đề với câu trả lời này. Đầu tiên, mọi chỉnh sửa thủ công /plugins/ios.jsonsẽ bị mất khi chạy cordova platform remove iostiếp theo cordova platform add ios. Thứ hai, @ Red2678 đã yêu cầu giải pháp "thực hiện chỉnh sửa theo chương trình thông qua Cordova ... để mục nhập mới được thêm vào lúc biên dịch."
TachyonVortex

3

Giải pháp @TachyonVortex có vẻ là lựa chọn tốt nhất nhưng đã gặp sự cố trong trường hợp của tôi. Sự cố do trường NSMainNibFile trống không được chuyển đổi đúng bởi gói NPM plist. Trong tệp .plist

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

được chuyển đổi thành:

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

Tôi đã sửa nó bằng cách thêm vào script:

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

Tập lệnh cuối cùng trông giống như (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' });

};

và config.xml:

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

Tôi đã viết một patch_plist.jstrong hooks/after_platform_addthư mục với mã này. Nhưng tôi vẫn nhận được <key>NSMainNibFile</key><string>NSMainNibFile~ipad</string>trong hồ sơ plist của mình. Bất kỳ ý tưởng về cách tôi có thể giải quyết vấn đề này xin vui lòng?
Romain R.


2

Vâng, nó là có thể!

Tôi đang sử dụng Cordova 9.0.0 (cordova-lib@9.0.1).

Ví dụ: đây là tệp cấu hình mà tôi đã sử dụng để chèn giá trị chuỗi mới vào 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>

Sau đó, đừng quên xây dựng lại tệp dàn của bạn bằng cách chạy hai lệnh này trong thiết bị đầu cuối của bạn:

cordova platform rm ios
cordova platform add ios

Để xác nhận thay đổi, bạn có thể kiểm tra tệp .plist mới được tạo bằng cách mở chúng bằng xCode.

-Info.plist tập tin đặt tại:

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

edit-configgiả sử mục tiêu đã tồn tại trong danh sách của bạn. Chỉ cần được rõ ràng, nếu bạn muốn thêm một cặp khóa / chuỗi mới, bạn nên sử dụng config-filethay vào đó, có thêm trẻ em mới vào cây xml
Daniel Lizik

1

Nếu bạn đang cố gắng sửa đổi một .plistplugin iOS gốc với một <config-file>thẻ trong của bạn plugin.xml, đây là những gì bạn cần làm:

  1. Đảm bảo rằng của bạn .plistlà xml, không phải nhị phân! Bạn có thể sử dụng plutilđể chuyển đổi một tệp nhị phân .plistthành xml và cam kết nó với quyền kiểm soát phiên bản.

    plutil -convert xml1 Info.plist

  2. Các hướng dẫn cho <config-file>chỉ ra rằng target=có liên quan đến dự án xcode được tạo tại platforms/ios/<project>/, nhưng tôi thấy rằng tôi cần thêm một ký tự đại diện vào đường dẫn của mình để làm cho nó hoạt động:

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

  3. Nếu bạn muốn thêm khóa ở cấp cao nhất của .plist, bạn cần đặt cấp độ gốc bằng tên khóa, sau đó lồng <string>thẻ với giá trị. Sử dụng một <array>hoặc <dict>như bất kỳ ví dụ hiển thị sẽ gây ra các phím này được lồng nhau dưới parent .

Đây là một ví dụ hoàn chỉnh phù hợp với tôi để thêm nhiều thuộc tính cấp cao nhất:

<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>

điều này đã không làm việc cho tôi. Tôi cố gắng thêm những gì bạn có ở trên, và không có gì thay đổi trong plist của tôi
Samuel Thompson

Hãy thử thu hẹp nguyên nhân bằng cách đặt plist vào thư mục gốc lúc đầu? Thật không may, tính năng này không thành công một cách âm thầm theo như tôi có thể nói.
Sky Kelsey

0

Tôi thích hook after_prepare hơn cho các dự án lớn hơn hoặc nếu bạn có nhiều plugin sử dụng các quyền giống nhau. Nhưng bạn luôn có thể đi theo cách đơn giản:

chỉ cần: - xóa plugin yêu cầu quyền mong muốn - thêm lại bằng --save - trong config.xml, plugin hiện có một biến mới với mô tả trống mà bạn có thể điền vào - bây giờ hãy xây dựng ios với - release và chúng sẽ được thiết lập.


-4

bạn chỉ cần làm theo các bước 1.

Tới dự án hàng hải Chọn mục tiêu Bấm vào thông tin từ tùy chọn tab tùy chọn khác là xây dựng khung cảnh xây dựng giai đoạn bạn sẽ thấy giá trị kiểu chìa khóa Khi bạn chỉ trên bất kỳ tên chính bạn sẽ tìm thấy + và - dấu hiệu nhấp chuột vào dấu + dấu hiệu ghi Key: GDLibraryModetrong phần then chốt Type:Stringtrong phần tyoe Value:GDEnterpriseSimulationtrong phần giá trị


1
Tôi hoàn toàn muốn làm điều này, nhưng khi tôi biên dịch ứng dụng Cordova từ CLI, thư mục của dự án về cơ bản đã bị xóa và được tạo lại. Sau đó, tôi sẽ phải làm như trên mỗi khi tôi biên dịch (không khó như vậy), nhưng tôi hy vọng chỉ sử dụng config.xml của Cordova để làm điều đó cho tôi.
Red2678,

bạn có thể vui lòng cho tôi biết tại sao nó yêu cầu để biên dịch thông qua của bạn chạy các ứng dụng thông qua xcode sau đó soluyion đây là tác phẩm cho bạn
Nitin

2
Xin chào @Nitin, Nó không phải là quá nhiều "yêu cầu" vì nó là cách tiêu chuẩn để sử dụng Cordova CLI. Nếu tôi sử dụng "lệnh Cordova build", thư mục dự án sẽ bị xóa và được tạo lại mỗi khi bạn chạy lệnh đó.
Red2678
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.