Merge pull request #87029 from bruvzg/info_plist_keys
[macOS/iOS export] Add option to set custom Info.plist data.
This commit is contained in:
commit
26b1fd0d84
|
@ -448,7 +448,9 @@ PList::PList() {
|
||||||
}
|
}
|
||||||
|
|
||||||
PList::PList(const String &p_string) {
|
PList::PList(const String &p_string) {
|
||||||
load_string(p_string);
|
String err_str;
|
||||||
|
bool ok = load_string(p_string, err_str);
|
||||||
|
ERR_FAIL_COND_MSG(!ok, "PList: " + err_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t PList::read_bplist_var_size_int(Ref<FileAccess> p_file, uint8_t p_size) {
|
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) {
|
||||||
|
|
||||||
String ret;
|
String ret;
|
||||||
ret.parse_utf8((const char *)array.ptr(), array.size());
|
ret.parse_utf8((const char *)array.ptr(), array.size());
|
||||||
return load_string(ret);
|
String err_str;
|
||||||
|
bool ok = load_string(ret, err_str);
|
||||||
|
ERR_FAIL_COND_V_MSG(!ok, false, "PList: " + err_str);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PList::load_string(const String &p_string) {
|
bool PList::load_string(const String &p_string, String &r_err_out) {
|
||||||
root = Ref<PListNode>();
|
root = Ref<PListNode>();
|
||||||
|
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
@ -657,14 +663,16 @@ bool PList::load_string(const String &p_string) {
|
||||||
while (pos >= 0) {
|
while (pos >= 0) {
|
||||||
int open_token_s = p_string.find("<", pos);
|
int open_token_s = p_string.find("<", pos);
|
||||||
if (open_token_s == -1) {
|
if (open_token_s == -1) {
|
||||||
ERR_FAIL_V_MSG(false, "PList: Unexpected end of data. No tags found.");
|
r_err_out = "Unexpected end of data. No tags found.";
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
int open_token_e = p_string.find(">", open_token_s);
|
int open_token_e = p_string.find(">", open_token_s);
|
||||||
pos = open_token_e;
|
pos = open_token_e;
|
||||||
|
|
||||||
String token = p_string.substr(open_token_s + 1, open_token_e - open_token_s - 1);
|
String token = p_string.substr(open_token_s + 1, open_token_e - open_token_s - 1);
|
||||||
if (token.is_empty()) {
|
if (token.is_empty()) {
|
||||||
ERR_FAIL_V_MSG(false, "PList: Invalid token name.");
|
r_err_out = "Invalid token name.";
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
String value;
|
String value;
|
||||||
if (token[0] == '?' || token[0] == '!') { // Skip <?xml ... ?> and <!DOCTYPE ... >
|
if (token[0] == '?' || token[0] == '!') { // Skip <?xml ... ?> and <!DOCTYPE ... >
|
||||||
|
@ -684,7 +692,8 @@ bool PList::load_string(const String &p_string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!in_plist) {
|
if (!in_plist) {
|
||||||
ERR_FAIL_V_MSG(false, "PList: Node outside of <plist> tag.");
|
r_err_out = "Node outside of <plist> tag.";
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token == "dict") {
|
if (token == "dict") {
|
||||||
|
@ -693,13 +702,15 @@ bool PList::load_string(const String &p_string) {
|
||||||
Ref<PListNode> dict = PListNode::new_dict();
|
Ref<PListNode> dict = PListNode::new_dict();
|
||||||
dict->data_type = PList::PLNodeType::PL_NODE_TYPE_DICT;
|
dict->data_type = PList::PLNodeType::PL_NODE_TYPE_DICT;
|
||||||
if (!stack.back()->get()->push_subnode(dict, key)) {
|
if (!stack.back()->get()->push_subnode(dict, key)) {
|
||||||
ERR_FAIL_V_MSG(false, "PList: Can't push subnode, invalid parent type.");
|
r_err_out = "Can't push subnode, invalid parent type.";
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
stack.push_back(dict);
|
stack.push_back(dict);
|
||||||
} else {
|
} else {
|
||||||
// Add root node.
|
// Add root node.
|
||||||
if (!root.is_null()) {
|
if (!root.is_null()) {
|
||||||
ERR_FAIL_V_MSG(false, "PList: Root node already set.");
|
r_err_out = "Root node already set.";
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
Ref<PListNode> dict = PListNode::new_dict();
|
Ref<PListNode> dict = PListNode::new_dict();
|
||||||
stack.push_back(dict);
|
stack.push_back(dict);
|
||||||
|
@ -711,7 +722,8 @@ bool PList::load_string(const String &p_string) {
|
||||||
if (token == "/dict") {
|
if (token == "/dict") {
|
||||||
// Exit current dict.
|
// Exit current dict.
|
||||||
if (stack.is_empty() || stack.back()->get()->data_type != PList::PLNodeType::PL_NODE_TYPE_DICT) {
|
if (stack.is_empty() || stack.back()->get()->data_type != PList::PLNodeType::PL_NODE_TYPE_DICT) {
|
||||||
ERR_FAIL_V_MSG(false, "PList: Mismatched </dict> tag.");
|
r_err_out = "Mismatched </dict> tag.";
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
stack.pop_back();
|
stack.pop_back();
|
||||||
continue;
|
continue;
|
||||||
|
@ -722,13 +734,15 @@ bool PList::load_string(const String &p_string) {
|
||||||
// Add subnode end enter it.
|
// Add subnode end enter it.
|
||||||
Ref<PListNode> arr = PListNode::new_array();
|
Ref<PListNode> arr = PListNode::new_array();
|
||||||
if (!stack.back()->get()->push_subnode(arr, key)) {
|
if (!stack.back()->get()->push_subnode(arr, key)) {
|
||||||
ERR_FAIL_V_MSG(false, "PList: Can't push subnode, invalid parent type.");
|
r_err_out = "Can't push subnode, invalid parent type.";
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
stack.push_back(arr);
|
stack.push_back(arr);
|
||||||
} else {
|
} else {
|
||||||
// Add root node.
|
// Add root node.
|
||||||
if (!root.is_null()) {
|
if (!root.is_null()) {
|
||||||
ERR_FAIL_V_MSG(false, "PList: Root node already set.");
|
r_err_out = "Root node already set.";
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
Ref<PListNode> arr = PListNode::new_array();
|
Ref<PListNode> arr = PListNode::new_array();
|
||||||
stack.push_back(arr);
|
stack.push_back(arr);
|
||||||
|
@ -740,7 +754,8 @@ bool PList::load_string(const String &p_string) {
|
||||||
if (token == "/array") {
|
if (token == "/array") {
|
||||||
// Exit current array.
|
// Exit current array.
|
||||||
if (stack.is_empty() || stack.back()->get()->data_type != PList::PLNodeType::PL_NODE_TYPE_ARRAY) {
|
if (stack.is_empty() || stack.back()->get()->data_type != PList::PLNodeType::PL_NODE_TYPE_ARRAY) {
|
||||||
ERR_FAIL_V_MSG(false, "PList: Mismatched </array> tag.");
|
r_err_out = "Mismatched </array> tag.";
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
stack.pop_back();
|
stack.pop_back();
|
||||||
continue;
|
continue;
|
||||||
|
@ -751,13 +766,15 @@ bool PList::load_string(const String &p_string) {
|
||||||
} else {
|
} else {
|
||||||
int end_token_s = p_string.find("</", pos);
|
int end_token_s = p_string.find("</", pos);
|
||||||
if (end_token_s == -1) {
|
if (end_token_s == -1) {
|
||||||
ERR_FAIL_V_MSG(false, vformat("PList: Mismatched <%s> tag.", token));
|
r_err_out = vformat("Mismatched <%s> tag.", token);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
int end_token_e = p_string.find(">", end_token_s);
|
int end_token_e = p_string.find(">", end_token_s);
|
||||||
pos = end_token_e;
|
pos = end_token_e;
|
||||||
String end_token = p_string.substr(end_token_s + 2, end_token_e - end_token_s - 2);
|
String end_token = p_string.substr(end_token_s + 2, end_token_e - end_token_s - 2);
|
||||||
if (end_token != token) {
|
if (end_token != token) {
|
||||||
ERR_FAIL_V_MSG(false, vformat("PList: Mismatched <%s> and <%s> token pair.", token, end_token));
|
r_err_out = vformat("Mismatched <%s> and <%s> token pair.", token, end_token);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
value = p_string.substr(open_token_e + 1, end_token_s - open_token_e - 1);
|
value = p_string.substr(open_token_e + 1, end_token_s - open_token_e - 1);
|
||||||
}
|
}
|
||||||
|
@ -780,15 +797,18 @@ bool PList::load_string(const String &p_string) {
|
||||||
} else if (token == "date") {
|
} else if (token == "date") {
|
||||||
var = PListNode::new_date(value);
|
var = PListNode::new_date(value);
|
||||||
} else {
|
} else {
|
||||||
ERR_FAIL_V_MSG(false, "PList: Invalid value type.");
|
r_err_out = vformat("Invalid value type: %s.", token);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
if (stack.is_empty() || !stack.back()->get()->push_subnode(var, key)) {
|
if (stack.is_empty() || !stack.back()->get()->push_subnode(var, key)) {
|
||||||
ERR_FAIL_V_MSG(false, "PList: Can't push subnode, invalid parent type.");
|
r_err_out = "Can't push subnode, invalid parent type.";
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!stack.is_empty() || !done_plist) {
|
if (!stack.is_empty() || !done_plist) {
|
||||||
ERR_FAIL_V_MSG(false, "PList: Unexpected end of data. Root node is not closed.");
|
r_err_out = "Unexpected end of data. Root node is not closed.";
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
|
@ -28,8 +28,8 @@
|
||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
#ifndef MACOS_PLIST_H
|
#ifndef PLIST_H
|
||||||
#define MACOS_PLIST_H
|
#define PLIST_H
|
||||||
|
|
||||||
// Property list file format (application/x-plist) parser, property list ASN-1 serialization.
|
// Property list file format (application/x-plist) parser, property list ASN-1 serialization.
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ public:
|
||||||
PList(const String &p_string);
|
PList(const String &p_string);
|
||||||
|
|
||||||
bool load_file(const String &p_filename);
|
bool load_file(const String &p_filename);
|
||||||
bool load_string(const String &p_string);
|
bool load_string(const String &p_string, String &r_err_out);
|
||||||
|
|
||||||
PackedByteArray save_asn1() const;
|
PackedByteArray save_asn1() const;
|
||||||
String save_text() const;
|
String save_text() const;
|
||||||
|
@ -125,4 +125,4 @@ public:
|
||||||
~PListNode() {}
|
~PListNode() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MACOS_PLIST_H
|
#endif // PLIST_H
|
|
@ -58,5 +58,6 @@ $usage_descriptions
|
||||||
</dict>
|
</dict>
|
||||||
<key>NSHighResolutionCapable</key>
|
<key>NSHighResolutionCapable</key>
|
||||||
$highres
|
$highres
|
||||||
|
$additional_plist_content
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -10,6 +10,13 @@
|
||||||
<link title="iOS plugins documentation index">$DOCS_URL/tutorials/platform/ios/index.html</link>
|
<link title="iOS plugins documentation index">$DOCS_URL/tutorials/platform/ios/index.html</link>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<members>
|
<members>
|
||||||
|
<member name="application/additional_plist_content" type="String" setter="" getter="">
|
||||||
|
Additional data added to the root [code]<dict>[/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.:
|
||||||
|
[codeblock]
|
||||||
|
<key>key_name</key>
|
||||||
|
<string>value</string>
|
||||||
|
[/codeblock]
|
||||||
|
</member>
|
||||||
<member name="application/app_store_team_id" type="String" setter="" getter="">
|
<member name="application/app_store_team_id" type="String" setter="" getter="">
|
||||||
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].
|
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].
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "run_icon_svg.gen.h"
|
#include "run_icon_svg.gen.h"
|
||||||
|
|
||||||
#include "core/io/json.h"
|
#include "core/io/json.h"
|
||||||
|
#include "core/io/plist.h"
|
||||||
#include "core/string/translation.h"
|
#include "core/string/translation.h"
|
||||||
#include "editor/editor_node.h"
|
#include "editor/editor_node.h"
|
||||||
#include "editor/editor_paths.h"
|
#include "editor/editor_paths.h"
|
||||||
|
@ -154,6 +155,8 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
|
||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/min_ios_version"), "12.0"));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/min_ios_version"), "12.0"));
|
||||||
|
|
||||||
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/additional_plist_content", PROPERTY_HINT_MULTILINE_TEXT), ""));
|
||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/icon_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/icon_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4));
|
||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "application/export_project_only"), false));
|
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
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
config_data.plist_content += p_preset->get("application/additional_plist_content").operator String() + "\n";
|
||||||
|
|
||||||
Vector<IOSExportAsset> assets;
|
Vector<IOSExportAsset> assets;
|
||||||
|
|
||||||
Ref<DirAccess> tmp_app_path = DirAccess::create_for_path(dest_dir);
|
Ref<DirAccess> tmp_app_path = DirAccess::create_for_path(dest_dir);
|
||||||
|
@ -1867,6 +1872,26 @@ bool EditorExportPlatformIOS::has_valid_export_configuration(const Ref<EditorExp
|
||||||
valid = dvalid || rvalid;
|
valid = dvalid || rvalid;
|
||||||
r_missing_templates = !valid;
|
r_missing_templates = !valid;
|
||||||
|
|
||||||
|
const String &additional_plist_content = p_preset->get("application/additional_plist_content");
|
||||||
|
if (!additional_plist_content.is_empty()) {
|
||||||
|
const String &plist = vformat("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
|
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
|
||||||
|
"<plist version=\"1.0\">"
|
||||||
|
"<dict>\n"
|
||||||
|
"%s\n"
|
||||||
|
"</dict>\n"
|
||||||
|
"</plist>\n",
|
||||||
|
additional_plist_content);
|
||||||
|
|
||||||
|
String plist_err;
|
||||||
|
Ref<PList> plist_parser;
|
||||||
|
plist_parser.instantiate();
|
||||||
|
if (!plist_parser->load_string(plist, plist_err)) {
|
||||||
|
err += TTR("Invalid additional PList content: ") + plist_err + "\n";
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!err.is_empty()) {
|
if (!err.is_empty()) {
|
||||||
r_error = err;
|
r_error = err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,13 @@
|
||||||
<link title="Running Godot apps on macOS">$DOCS_URL/tutorials//export/running_on_macos.html</link>
|
<link title="Running Godot apps on macOS">$DOCS_URL/tutorials//export/running_on_macos.html</link>
|
||||||
</tutorials>
|
</tutorials>
|
||||||
<members>
|
<members>
|
||||||
|
<member name="application/additional_plist_content" type="String" setter="" getter="">
|
||||||
|
Additional data added to the root [code]<dict>[/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.:
|
||||||
|
[codeblock]
|
||||||
|
<key>key_name</key>
|
||||||
|
<string>value</string>
|
||||||
|
[/codeblock]
|
||||||
|
</member>
|
||||||
<member name="application/app_category" type="String" setter="" getter="">
|
<member name="application/app_category" type="String" setter="" getter="">
|
||||||
Application category for the App Store.
|
Application category for the App Store.
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
|
|
||||||
#include "lipo.h"
|
#include "lipo.h"
|
||||||
#include "macho.h"
|
#include "macho.h"
|
||||||
#include "plist.h"
|
|
||||||
|
|
||||||
|
#include "core/io/plist.h"
|
||||||
#include "core/os/os.h"
|
#include "core/os/os.h"
|
||||||
#include "editor/editor_paths.h"
|
#include "editor/editor_paths.h"
|
||||||
#include "editor/editor_settings.h"
|
#include "editor/editor_settings.h"
|
||||||
|
|
|
@ -41,11 +41,10 @@
|
||||||
// - Requirements code generator is not implemented (only hard-coded requirements for the ad-hoc signing is supported).
|
// - Requirements code generator is not implemented (only hard-coded requirements for the ad-hoc signing is supported).
|
||||||
// - RFC5652/CMS blob generation is not implemented, supports ad-hoc signing only.
|
// - RFC5652/CMS blob generation is not implemented, supports ad-hoc signing only.
|
||||||
|
|
||||||
#include "plist.h"
|
|
||||||
|
|
||||||
#include "core/crypto/crypto_core.h"
|
#include "core/crypto/crypto_core.h"
|
||||||
#include "core/io/dir_access.h"
|
#include "core/io/dir_access.h"
|
||||||
#include "core/io/file_access.h"
|
#include "core/io/file_access.h"
|
||||||
|
#include "core/io/plist.h"
|
||||||
#include "core/object/ref_counted.h"
|
#include "core/object/ref_counted.h"
|
||||||
|
|
||||||
#include "modules/modules_enabled.gen.h" // For regex.
|
#include "modules/modules_enabled.gen.h" // For regex.
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "run_icon_svg.gen.h"
|
#include "run_icon_svg.gen.h"
|
||||||
|
|
||||||
#include "core/io/image_loader.h"
|
#include "core/io/image_loader.h"
|
||||||
|
#include "core/io/plist.h"
|
||||||
#include "core/string/translation.h"
|
#include "core/string/translation.h"
|
||||||
#include "drivers/png/png_driver_common.h"
|
#include "drivers/png/png_driver_common.h"
|
||||||
#include "editor/editor_node.h"
|
#include "editor/editor_node.h"
|
||||||
|
@ -388,6 +389,8 @@ void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_angle", PROPERTY_HINT_ENUM, "Auto,Yes,No"), 0, true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_angle", PROPERTY_HINT_ENUM, "Auto,Yes,No"), 0, true));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "display/high_res"), true));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "display/high_res"), true));
|
||||||
|
|
||||||
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/additional_plist_content", PROPERTY_HINT_MULTILINE_TEXT), ""));
|
||||||
|
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/platform_build"), "14C18"));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/platform_build"), "14C18"));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/sdk_version"), "13.1"));
|
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/sdk_version"), "13.1"));
|
||||||
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/sdk_build"), "22C55"));
|
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
|
||||||
strnew += lines[i].replace("$min_version", p_preset->get("application/min_macos_version")) + "\n";
|
strnew += lines[i].replace("$min_version", p_preset->get("application/min_macos_version")) + "\n";
|
||||||
} else if (lines[i].find("$highres") != -1) {
|
} else if (lines[i].find("$highres") != -1) {
|
||||||
strnew += lines[i].replace("$highres", p_preset->get("display/high_res") ? "\t<true/>" : "\t<false/>") + "\n";
|
strnew += lines[i].replace("$highres", p_preset->get("display/high_res") ? "\t<true/>" : "\t<false/>") + "\n";
|
||||||
|
} else if (lines[i].find("$additional_plist_content") != -1) {
|
||||||
|
strnew += lines[i].replace("$additional_plist_content", p_preset->get("application/additional_plist_content")) + "\n";
|
||||||
} else if (lines[i].find("$platfbuild") != -1) {
|
} else if (lines[i].find("$platfbuild") != -1) {
|
||||||
strnew += lines[i].replace("$platfbuild", p_preset->get("xcode/platform_build")) + "\n";
|
strnew += lines[i].replace("$platfbuild", p_preset->get("xcode/platform_build")) + "\n";
|
||||||
} else if (lines[i].find("$sdkver") != -1) {
|
} else if (lines[i].find("$sdkver") != -1) {
|
||||||
|
@ -2095,6 +2100,26 @@ bool EditorExportPlatformMacOS::has_valid_project_configuration(const Ref<Editor
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const String &additional_plist_content = p_preset->get("application/additional_plist_content");
|
||||||
|
if (!additional_plist_content.is_empty()) {
|
||||||
|
const String &plist = vformat("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||||
|
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
|
||||||
|
"<plist version=\"1.0\">"
|
||||||
|
"<dict>\n"
|
||||||
|
"%s\n"
|
||||||
|
"</dict>\n"
|
||||||
|
"</plist>\n",
|
||||||
|
additional_plist_content);
|
||||||
|
|
||||||
|
String plist_err;
|
||||||
|
Ref<PList> plist_parser;
|
||||||
|
plist_parser.instantiate();
|
||||||
|
if (!plist_parser->load_string(plist, plist_err)) {
|
||||||
|
err += TTR("Invalid additional PList content: ") + plist_err + "\n";
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<ExportOption> options;
|
List<ExportOption> options;
|
||||||
get_export_options(&options);
|
get_export_options(&options);
|
||||||
for (const EditorExportPlatform::ExportOption &E : options) {
|
for (const EditorExportPlatform::ExportOption &E : options) {
|
||||||
|
|
Loading…
Reference in New Issue