Skip to content

Commit 26b1fd0

Browse files
committed
Merge pull request #87029 from bruvzg/info_plist_keys
[macOS/iOS export] Add option to set custom Info.plist data.
2 parents 8616487 + 4910772 commit 26b1fd0

File tree

9 files changed

+108
-24
lines changed

9 files changed

+108
-24
lines changed
Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,9 @@ PList::PList() {
448448
}
449449

450450
PList::PList(const String &p_string) {
451-
load_string(p_string);
451+
String err_str;
452+
bool ok = load_string(p_string, err_str);
453+
ERR_FAIL_COND_MSG(!ok, "PList: " + err_str);
452454
}
453455

454456
uint64_t PList::read_bplist_var_size_int(Ref<FileAccess> p_file, uint8_t p_size) {
@@ -642,11 +644,15 @@ bool PList::load_file(const String &p_filename) {
642644

643645
String ret;
644646
ret.parse_utf8((const char *)array.ptr(), array.size());
645-
return load_string(ret);
647+
String err_str;
648+
bool ok = load_string(ret, err_str);
649+
ERR_FAIL_COND_V_MSG(!ok, false, "PList: " + err_str);
650+
651+
return true;
646652
}
647653
}
648654

649-
bool PList::load_string(const String &p_string) {
655+
bool PList::load_string(const String &p_string, String &r_err_out) {
650656
root = Ref<PListNode>();
651657

652658
int pos = 0;
@@ -657,14 +663,16 @@ bool PList::load_string(const String &p_string) {
657663
while (pos >= 0) {
658664
int open_token_s = p_string.find("<", pos);
659665
if (open_token_s == -1) {
660-
ERR_FAIL_V_MSG(false, "PList: Unexpected end of data. No tags found.");
666+
r_err_out = "Unexpected end of data. No tags found.";
667+
return false;
661668
}
662669
int open_token_e = p_string.find(">", open_token_s);
663670
pos = open_token_e;
664671

665672
String token = p_string.substr(open_token_s + 1, open_token_e - open_token_s - 1);
666673
if (token.is_empty()) {
667-
ERR_FAIL_V_MSG(false, "PList: Invalid token name.");
674+
r_err_out = "Invalid token name.";
675+
return false;
668676
}
669677
String value;
670678
if (token[0] == '?' || token[0] == '!') { // Skip <?xml ... ?> and <!DOCTYPE ... >
@@ -684,7 +692,8 @@ bool PList::load_string(const String &p_string) {
684692
}
685693

686694
if (!in_plist) {
687-
ERR_FAIL_V_MSG(false, "PList: Node outside of <plist> tag.");
695+
r_err_out = "Node outside of <plist> tag.";
696+
return false;
688697
}
689698

690699
if (token == "dict") {
@@ -693,13 +702,15 @@ bool PList::load_string(const String &p_string) {
693702
Ref<PListNode> dict = PListNode::new_dict();
694703
dict->data_type = PList::PLNodeType::PL_NODE_TYPE_DICT;
695704
if (!stack.back()->get()->push_subnode(dict, key)) {
696-
ERR_FAIL_V_MSG(false, "PList: Can't push subnode, invalid parent type.");
705+
r_err_out = "Can't push subnode, invalid parent type.";
706+
return false;
697707
}
698708
stack.push_back(dict);
699709
} else {
700710
// Add root node.
701711
if (!root.is_null()) {
702-
ERR_FAIL_V_MSG(false, "PList: Root node already set.");
712+
r_err_out = "Root node already set.";
713+
return false;
703714
}
704715
Ref<PListNode> dict = PListNode::new_dict();
705716
stack.push_back(dict);
@@ -711,7 +722,8 @@ bool PList::load_string(const String &p_string) {
711722
if (token == "/dict") {
712723
// Exit current dict.
713724
if (stack.is_empty() || stack.back()->get()->data_type != PList::PLNodeType::PL_NODE_TYPE_DICT) {
714-
ERR_FAIL_V_MSG(false, "PList: Mismatched </dict> tag.");
725+
r_err_out = "Mismatched </dict> tag.";
726+
return false;
715727
}
716728
stack.pop_back();
717729
continue;
@@ -722,13 +734,15 @@ bool PList::load_string(const String &p_string) {
722734
// Add subnode end enter it.
723735
Ref<PListNode> arr = PListNode::new_array();
724736
if (!stack.back()->get()->push_subnode(arr, key)) {
725-
ERR_FAIL_V_MSG(false, "PList: Can't push subnode, invalid parent type.");
737+
r_err_out = "Can't push subnode, invalid parent type.";
738+
return false;
726739
}
727740
stack.push_back(arr);
728741
} else {
729742
// Add root node.
730743
if (!root.is_null()) {
731-
ERR_FAIL_V_MSG(false, "PList: Root node already set.");
744+
r_err_out = "Root node already set.";
745+
return false;
732746
}
733747
Ref<PListNode> arr = PListNode::new_array();
734748
stack.push_back(arr);
@@ -740,7 +754,8 @@ bool PList::load_string(const String &p_string) {
740754
if (token == "/array") {
741755
// Exit current array.
742756
if (stack.is_empty() || stack.back()->get()->data_type != PList::PLNodeType::PL_NODE_TYPE_ARRAY) {
743-
ERR_FAIL_V_MSG(false, "PList: Mismatched </array> tag.");
757+
r_err_out = "Mismatched </array> tag.";
758+
return false;
744759
}
745760
stack.pop_back();
746761
continue;
@@ -751,13 +766,15 @@ bool PList::load_string(const String &p_string) {
751766
} else {
752767
int end_token_s = p_string.find("</", pos);
753768
if (end_token_s == -1) {
754-
ERR_FAIL_V_MSG(false, vformat("PList: Mismatched <%s> tag.", token));
769+
r_err_out = vformat("Mismatched <%s> tag.", token);
770+
return false;
755771
}
756772
int end_token_e = p_string.find(">", end_token_s);
757773
pos = end_token_e;
758774
String end_token = p_string.substr(end_token_s + 2, end_token_e - end_token_s - 2);
759775
if (end_token != token) {
760-
ERR_FAIL_V_MSG(false, vformat("PList: Mismatched <%s> and <%s> token pair.", token, end_token));
776+
r_err_out = vformat("Mismatched <%s> and <%s> token pair.", token, end_token);
777+
return false;
761778
}
762779
value = p_string.substr(open_token_e + 1, end_token_s - open_token_e - 1);
763780
}
@@ -780,15 +797,18 @@ bool PList::load_string(const String &p_string) {
780797
} else if (token == "date") {
781798
var = PListNode::new_date(value);
782799
} else {
783-
ERR_FAIL_V_MSG(false, "PList: Invalid value type.");
800+
r_err_out = vformat("Invalid value type: %s.", token);
801+
return false;
784802
}
785803
if (stack.is_empty() || !stack.back()->get()->push_subnode(var, key)) {
786-
ERR_FAIL_V_MSG(false, "PList: Can't push subnode, invalid parent type.");
804+
r_err_out = "Can't push subnode, invalid parent type.";
805+
return false;
787806
}
788807
}
789808
}
790809
if (!stack.is_empty() || !done_plist) {
791-
ERR_FAIL_V_MSG(false, "PList: Unexpected end of data. Root node is not closed.");
810+
r_err_out = "Unexpected end of data. Root node is not closed.";
811+
return false;
792812
}
793813
return true;
794814
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
2929
/**************************************************************************/
3030

31-
#ifndef MACOS_PLIST_H
32-
#define MACOS_PLIST_H
31+
#ifndef PLIST_H
32+
#define PLIST_H
3333

3434
// Property list file format (application/x-plist) parser, property list ASN-1 serialization.
3535

@@ -75,7 +75,7 @@ class PList : public RefCounted {
7575
PList(const String &p_string);
7676

7777
bool load_file(const String &p_filename);
78-
bool load_string(const String &p_string);
78+
bool load_string(const String &p_string, String &r_err_out);
7979

8080
PackedByteArray save_asn1() const;
8181
String save_text() const;
@@ -125,4 +125,4 @@ class PListNode : public RefCounted {
125125
~PListNode() {}
126126
};
127127

128-
#endif // MACOS_PLIST_H
128+
#endif // PLIST_H

misc/dist/macos_template.app/Contents/Info.plist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,6 @@ $usage_descriptions
5858
</dict>
5959
<key>NSHighResolutionCapable</key>
6060
$highres
61+
$additional_plist_content
6162
</dict>
6263
</plist>

platform/ios/doc_classes/EditorExportPlatformIOS.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
<link title="iOS plugins documentation index">$DOCS_URL/tutorials/platform/ios/index.html</link>
1111
</tutorials>
1212
<members>
13+
<member name="application/additional_plist_content" type="String" setter="" getter="">
14+
Additional data added to the root [code]&lt;dict&gt;[/code] section of the [url=https://developer.apple.com/documentation/bundleresources/information_property_list]Info.plist[/url] file. The value should be an XML section with pairs of key-value elements, e.g.:
15+
[codeblock]
16+
&lt;key&gt;key_name&lt;/key&gt;
17+
&lt;string&gt;value&lt;/string&gt;
18+
[/codeblock]
19+
</member>
1320
<member name="application/app_store_team_id" type="String" setter="" getter="">
1421
Apple Team ID, unique 10-character string. To locate your Team ID check "Membership details" section in your Apple developer account dashboard, or "Organizational Unit" of your code signing certificate. See [url=https://developer.apple.com/help/account/manage-your-team/locate-your-team-id]Locate your Team ID[/url].
1522
</member>

platform/ios/export/export_plugin.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "run_icon_svg.gen.h"
3535

3636
#include "core/io/json.h"
37+
#include "core/io/plist.h"
3738
#include "core/string/translation.h"
3839
#include "editor/editor_node.h"
3940
#include "editor/editor_paths.h"
@@ -154,6 +155,8 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
154155

155156
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/min_ios_version"), "12.0"));
156157

158+
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/additional_plist_content", PROPERTY_HINT_MULTILINE_TEXT), ""));
159+
157160
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/icon_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4));
158161

159162
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "application/export_project_only"), false));
@@ -1498,6 +1501,8 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
14981501
false
14991502
};
15001503

1504+
config_data.plist_content += p_preset->get("application/additional_plist_content").operator String() + "\n";
1505+
15011506
Vector<IOSExportAsset> assets;
15021507

15031508
Ref<DirAccess> tmp_app_path = DirAccess::create_for_path(dest_dir);
@@ -1867,6 +1872,26 @@ bool EditorExportPlatformIOS::has_valid_export_configuration(const Ref<EditorExp
18671872
valid = dvalid || rvalid;
18681873
r_missing_templates = !valid;
18691874

1875+
const String &additional_plist_content = p_preset->get("application/additional_plist_content");
1876+
if (!additional_plist_content.is_empty()) {
1877+
const String &plist = vformat("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1878+
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
1879+
"<plist version=\"1.0\">"
1880+
"<dict>\n"
1881+
"%s\n"
1882+
"</dict>\n"
1883+
"</plist>\n",
1884+
additional_plist_content);
1885+
1886+
String plist_err;
1887+
Ref<PList> plist_parser;
1888+
plist_parser.instantiate();
1889+
if (!plist_parser->load_string(plist, plist_err)) {
1890+
err += TTR("Invalid additional PList content: ") + plist_err + "\n";
1891+
valid = false;
1892+
}
1893+
}
1894+
18701895
if (!err.is_empty()) {
18711896
r_error = err;
18721897
}

platform/macos/doc_classes/EditorExportPlatformMacOS.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
<link title="Running Godot apps on macOS">$DOCS_URL/tutorials//export/running_on_macos.html</link>
1111
</tutorials>
1212
<members>
13+
<member name="application/additional_plist_content" type="String" setter="" getter="">
14+
Additional data added to the root [code]&lt;dict&gt;[/code] section of the [url=https://developer.apple.com/documentation/bundleresources/information_property_list]Info.plist[/url] file. The value should be an XML section with pairs of key-value elements, e.g.:
15+
[codeblock]
16+
&lt;key&gt;key_name&lt;/key&gt;
17+
&lt;string&gt;value&lt;/string&gt;
18+
[/codeblock]
19+
</member>
1320
<member name="application/app_category" type="String" setter="" getter="">
1421
Application category for the App Store.
1522
</member>

platform/macos/export/codesign.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232

3333
#include "lipo.h"
3434
#include "macho.h"
35-
#include "plist.h"
3635

36+
#include "core/io/plist.h"
3737
#include "core/os/os.h"
3838
#include "editor/editor_paths.h"
3939
#include "editor/editor_settings.h"

platform/macos/export/codesign.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,10 @@
4141
// - Requirements code generator is not implemented (only hard-coded requirements for the ad-hoc signing is supported).
4242
// - RFC5652/CMS blob generation is not implemented, supports ad-hoc signing only.
4343

44-
#include "plist.h"
45-
4644
#include "core/crypto/crypto_core.h"
4745
#include "core/io/dir_access.h"
4846
#include "core/io/file_access.h"
47+
#include "core/io/plist.h"
4948
#include "core/object/ref_counted.h"
5049

5150
#include "modules/modules_enabled.gen.h" // For regex.

platform/macos/export/export_plugin.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "run_icon_svg.gen.h"
3838

3939
#include "core/io/image_loader.h"
40+
#include "core/io/plist.h"
4041
#include "core/string/translation.h"
4142
#include "drivers/png/png_driver_common.h"
4243
#include "editor/editor_node.h"
@@ -388,6 +389,8 @@ void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options
388389
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_angle", PROPERTY_HINT_ENUM, "Auto,Yes,No"), 0, true));
389390
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "display/high_res"), true));
390391

392+
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/additional_plist_content", PROPERTY_HINT_MULTILINE_TEXT), ""));
393+
391394
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/platform_build"), "14C18"));
392395
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/sdk_version"), "13.1"));
393396
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/sdk_build"), "22C55"));
@@ -672,6 +675,8 @@ void EditorExportPlatformMacOS::_fix_plist(const Ref<EditorExportPreset> &p_pres
672675
strnew += lines[i].replace("$min_version", p_preset->get("application/min_macos_version")) + "\n";
673676
} else if (lines[i].find("$highres") != -1) {
674677
strnew += lines[i].replace("$highres", p_preset->get("display/high_res") ? "\t<true/>" : "\t<false/>") + "\n";
678+
} else if (lines[i].find("$additional_plist_content") != -1) {
679+
strnew += lines[i].replace("$additional_plist_content", p_preset->get("application/additional_plist_content")) + "\n";
675680
} else if (lines[i].find("$platfbuild") != -1) {
676681
strnew += lines[i].replace("$platfbuild", p_preset->get("xcode/platform_build")) + "\n";
677682
} else if (lines[i].find("$sdkver") != -1) {
@@ -2095,6 +2100,26 @@ bool EditorExportPlatformMacOS::has_valid_project_configuration(const Ref<Editor
20952100
};
20962101
}
20972102

2103+
const String &additional_plist_content = p_preset->get("application/additional_plist_content");
2104+
if (!additional_plist_content.is_empty()) {
2105+
const String &plist = vformat("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
2106+
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
2107+
"<plist version=\"1.0\">"
2108+
"<dict>\n"
2109+
"%s\n"
2110+
"</dict>\n"
2111+
"</plist>\n",
2112+
additional_plist_content);
2113+
2114+
String plist_err;
2115+
Ref<PList> plist_parser;
2116+
plist_parser.instantiate();
2117+
if (!plist_parser->load_string(plist, plist_err)) {
2118+
err += TTR("Invalid additional PList content: ") + plist_err + "\n";
2119+
valid = false;
2120+
}
2121+
}
2122+
20982123
List<ExportOption> options;
20992124
get_export_options(&options);
21002125
for (const EditorExportPlatform::ExportOption &E : options) {

0 commit comments

Comments
 (0)