|
@@ -0,0 +1,270 @@
|
|
|
+---
|
|
|
+title: Нативные расширения - Инструменты Слияния Манифестов
|
|
|
+brief: В данном руководстве описывается работа по слиянию манифестов приложений
|
|
|
+---
|
|
|
+
|
|
|
+# Манифесты приложений
|
|
|
+
|
|
|
+Для некоторых платформ мы поддерживаем расширения, поставляющие фрагменты (или заглушки) манифестов приложений.
|
|
|
+Он может быть частью `AndroidManifest.xml`, `Info.plist` или `engine_template.html`.
|
|
|
+
|
|
|
+Каждая заглушка манифеста расширения будет применяться последовательно, начиная с базового манифеста приложения.
|
|
|
+Базовый манифест - это либо манифест по умолчанию (в `builtins\manifests\<platforms>\...`), либо пользовательский манифест, указанный пользователем.
|
|
|
+
|
|
|
+## Именования и Структуры
|
|
|
+
|
|
|
+Манифесты расширения должны быть помещены в определенную структуру, чтобы расширение функционировало по назначению.
|
|
|
+
|
|
|
+ /myextension
|
|
|
+ ext.manifest
|
|
|
+ /manifests
|
|
|
+ /android
|
|
|
+ AndroidManifest.xml
|
|
|
+ /ios
|
|
|
+ Info.plist
|
|
|
+ /osx
|
|
|
+ Info.plist
|
|
|
+ /web
|
|
|
+ engine_template.html
|
|
|
+
|
|
|
+
|
|
|
+## Android
|
|
|
+
|
|
|
+Платформа Android уже имеет инструмент слияния манифестов (основанный на `ManifestMerger2`), и мы используем его внутри `bob.jar` для слияния манифестов.
|
|
|
+Для получения полного набора инструкций по изменению манифестов Android, пожалуйста, обратитесь к [документации](https://developer.android.com/studio/build/manifest-merge)
|
|
|
+
|
|
|
+::: important
|
|
|
+Если вы не установите `android:targetSdkVersion` в манифесте расширения, следующие разрешения, они будут добавлены автоматически: `WRITE_EXTERNAL_STORAGE`, `READ_PHONE_STATE`, `READ_EXTERNAL_STORAGE`. Подробнее об этом можно прочитать в официальной [документации](https://developer.android.com/studio/build/manifest-merge#implicit_system_permissions).
|
|
|
+Мы рекомендуем использовать: `<uses-sdk android:targetSdkVersion=“{{android.target_sdk_version}}” />`
|
|
|
+:::
|
|
|
+### Пример
|
|
|
+
|
|
|
+Базовый манифест:
|
|
|
+
|
|
|
+```xml
|
|
|
+ <?xml version='1.0' encoding='utf-8'?>
|
|
|
+ <manifest xmlns:android='http://schemas.android.com/apk/res/android'
|
|
|
+ package='com.defold.testmerge'
|
|
|
+ android:versionCode='14'
|
|
|
+ android:versionName='1.0'
|
|
|
+ android:installLocation='auto'>
|
|
|
+ <uses-feature android:required='true' android:glEsVersion='0x00020000' />
|
|
|
+ <uses-sdk android:minSdkVersion='9' android:targetSdkVersion='26' />
|
|
|
+ <application android:label='Test Project' android:hasCode='true'>
|
|
|
+ </application>
|
|
|
+ <uses-permission android:name='android.permission.VIBRATE' />
|
|
|
+ </manifest>
|
|
|
+```
|
|
|
+
|
|
|
+Манифест расширения:
|
|
|
+
|
|
|
+```xml
|
|
|
+ <?xml version='1.0' encoding='utf-8'?>
|
|
|
+ <manifest xmlns:android='http://schemas.android.com/apk/res/android' package='com.defold.testmerge'>
|
|
|
+ <uses-sdk android:targetSdkVersion=“{{android.target_sdk_version}}” />
|
|
|
+ <uses-feature android:required='true' android:glEsVersion='0x00030000' />
|
|
|
+ <application>
|
|
|
+ <meta-data android:name='com.facebook.sdk.ApplicationName'
|
|
|
+ android:value='Test Project' />
|
|
|
+ <activity android:name='com.facebook.FacebookActivity'
|
|
|
+ android:theme='@android:style/Theme.Translucent.NoTitleBar'
|
|
|
+ android:configChanges='keyboard|keyboardHidden|screenLayout|screenSize|orientation'
|
|
|
+ android:label='Test Project' />
|
|
|
+ </application>
|
|
|
+ </manifest>
|
|
|
+```
|
|
|
+
|
|
|
+Результат:
|
|
|
+
|
|
|
+```xml
|
|
|
+ <?xml version='1.0' encoding='utf-8'?>
|
|
|
+ <manifest xmlns:android='http://schemas.android.com/apk/res/android'
|
|
|
+ package='com.defold.testmerge'
|
|
|
+ android:installLocation='auto'
|
|
|
+ android:versionCode='14'
|
|
|
+ android:versionName='1.0' >
|
|
|
+ <uses-sdk
|
|
|
+ android:minSdkVersion='9'
|
|
|
+ android:targetSdkVersion='26' />
|
|
|
+ <uses-permission android:name='android.permission.VIBRATE' />
|
|
|
+ <uses-feature
|
|
|
+ android:glEsVersion='0x00030000'
|
|
|
+ android:required='true' />
|
|
|
+ <application
|
|
|
+ android:hasCode='true'
|
|
|
+ android:label='Test Project' >
|
|
|
+ <meta-data
|
|
|
+ android:name='com.facebook.sdk.ApplicationName'
|
|
|
+ android:value='Test Project' />
|
|
|
+ <activity
|
|
|
+ android:name='com.facebook.FacebookActivity'
|
|
|
+ android:configChanges='keyboard|keyboardHidden|screenLayout|screenSize|orientation'
|
|
|
+ android:label='Test Project'
|
|
|
+ android:theme='@android:style/Theme.Translucent.NoTitleBar' />
|
|
|
+ </application>
|
|
|
+ </manifest>
|
|
|
+```
|
|
|
+
|
|
|
+## iOS / macOS
|
|
|
+
|
|
|
+Для `Info.plist` мы используем нашу собственную реализацию для объединения двух списков свойств.
|
|
|
+Они могут работать со списками и словарями.
|
|
|
+
|
|
|
+### Пример
|
|
|
+
|
|
|
+Базовый манифест:
|
|
|
+
|
|
|
+```xml
|
|
|
+ <?xml version='1.0' encoding='UTF-8'?>
|
|
|
+ <!DOCTYPE plist PUBLIC '-//Apple//DTD PLIST 1.0//EN' 'http://www.apple.com/DTDs/PropertyList-1.0.dtd'>
|
|
|
+ <plist version='1.0'>
|
|
|
+ <dict>
|
|
|
+ <key>NSAppTransportSecurity</key>
|
|
|
+ <dict>
|
|
|
+ <key>NSExceptionDomains</key>
|
|
|
+ <dict>
|
|
|
+ <key>foobar.net</key>
|
|
|
+ <dict>
|
|
|
+ <key>testproperty</key>
|
|
|
+ <true/>
|
|
|
+ </dict>
|
|
|
+ </dict>
|
|
|
+ </dict>
|
|
|
+ <key>INT</key>
|
|
|
+ <integer>8</integer>
|
|
|
+ <key>REAL</key>
|
|
|
+ <real>8.0</real>
|
|
|
+ <key>BASE64</key>
|
|
|
+ <data>SEVMTE8gV09STEQ=</data>
|
|
|
+ </dict>
|
|
|
+ </plist>
|
|
|
+```
|
|
|
+
|
|
|
+Манифест расширения:
|
|
|
+
|
|
|
+```xml
|
|
|
+ <?xml version='1.0' encoding='UTF-8'?>
|
|
|
+ <!DOCTYPE plist PUBLIC '-//Apple//DTD PLIST 1.0//EN' 'http://www.apple.com/DTDs/PropertyList-1.0.dtd'>
|
|
|
+ <plist version='1.0'>
|
|
|
+ <dict>
|
|
|
+ <key>NSAppTransportSecurity</key>
|
|
|
+ <dict>
|
|
|
+ <key>NSExceptionDomains</key>
|
|
|
+ <dict>
|
|
|
+ <key>facebook.com</key>
|
|
|
+ <dict>
|
|
|
+ <key>NSIncludesSubdomains</key>
|
|
|
+ <true/>
|
|
|
+ <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
|
|
|
+ <false/>
|
|
|
+ </dict>
|
|
|
+ </dict>
|
|
|
+ </dict>
|
|
|
+ <key>INT</key>
|
|
|
+ <integer>42</integer>
|
|
|
+ </dict>
|
|
|
+ </plist>
|
|
|
+```
|
|
|
+
|
|
|
+Результат:
|
|
|
+
|
|
|
+```xml
|
|
|
+ <?xml version='1.0'?>
|
|
|
+ <!DOCTYPE plist SYSTEM 'file://localhost/System/Library/DTDs/PropertyList.dtd'>
|
|
|
+ <plist version='1.0'>
|
|
|
+ <dict>
|
|
|
+ <key>NSAppTransportSecurity</key>
|
|
|
+ <dict>
|
|
|
+ <key>NSExceptionDomains</key>
|
|
|
+ <dict>
|
|
|
+ <key>foobar.net</key>
|
|
|
+ <dict>
|
|
|
+ <key>testproperty</key>
|
|
|
+ <true/>
|
|
|
+ </dict>
|
|
|
+ <key>facebook.com</key>
|
|
|
+ <dict>
|
|
|
+ <key>NSIncludesSubdomains</key>
|
|
|
+ <true/>
|
|
|
+ <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
|
|
|
+ <false/>
|
|
|
+ </dict>
|
|
|
+ </dict>
|
|
|
+ </dict>
|
|
|
+ <key>INT</key>
|
|
|
+ <integer>8</integer>
|
|
|
+ <key>REAL</key>
|
|
|
+ <real>8.0</real>
|
|
|
+ <key>BASE64</key>
|
|
|
+ <data>SEVMTE8gV09STEQ=</data>
|
|
|
+ <key>INT</key>
|
|
|
+ <integer>42</integer>
|
|
|
+ </dict>
|
|
|
+ </plist>
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+## HTML5
|
|
|
+
|
|
|
+Для html-шаблона мы дали название каждому разделу, чтобы можно было их сопоставить (например, "engine-start").
|
|
|
+Вы можете указать атрибуты `merge` или `keep`. По умолчанию используется `merge`.
|
|
|
+
|
|
|
+### Пример
|
|
|
+
|
|
|
+Базовый манифест:
|
|
|
+
|
|
|
+```html
|
|
|
+ <!DOCTYPE html>
|
|
|
+ <html>
|
|
|
+ <body>
|
|
|
+ <script id='engine-loader' type='text/javascript' src='dmloader.js'></script>
|
|
|
+ <script id='engine-setup' type='text/javascript'>
|
|
|
+ function load_engine() {
|
|
|
+ var engineJS = document.createElement('script');
|
|
|
+ engineJS.type = 'text/javascript';
|
|
|
+ engineJS.src = '{{exe-name}}_wasm.js';
|
|
|
+ document.head.appendChild(engineJS);
|
|
|
+ }
|
|
|
+ </script>
|
|
|
+ <script id='engine-start' type='text/javascript'>
|
|
|
+ load_engine();
|
|
|
+ </script>
|
|
|
+ </body>
|
|
|
+ </html>
|
|
|
+```
|
|
|
+
|
|
|
+Манифест расширения:
|
|
|
+
|
|
|
+```html
|
|
|
+ <html>
|
|
|
+ <body>
|
|
|
+ <script id='engine-loader' type='text/javascript' src='mydmloader.js'></script>
|
|
|
+ <script id='engine-start' type='text/javascript' merge='keep'>
|
|
|
+ my_load_engine();
|
|
|
+ </script>
|
|
|
+ </body>
|
|
|
+ </html>
|
|
|
+```
|
|
|
+
|
|
|
+Результат:
|
|
|
+
|
|
|
+```html
|
|
|
+ <!doctype html>
|
|
|
+ <html>
|
|
|
+ <head></head>
|
|
|
+ <body>
|
|
|
+ <script id='engine-loader' type='text/javascript' src='mydmloader.js'></script>
|
|
|
+ <script id='engine-setup' type='text/javascript'>
|
|
|
+ function load_engine() {
|
|
|
+ var engineJSdocument.createElement('script');
|
|
|
+ engineJS.type = 'text/javascript';
|
|
|
+ engineJS.src = '{{exe-name}}_wasm.js';
|
|
|
+ document.head.appendChild(engineJS);
|
|
|
+ }
|
|
|
+ </script>
|
|
|
+ <script id='engine-start' type='text/javascript' merge='keep'>
|
|
|
+ my_load_engine(
|
|
|
+ </script>
|
|
|
+ </body>
|
|
|
+ </html>
|
|
|
+```
|