├── Assets
├── Resources
│ ├── BillingMode.json
│ └── BillingMode.json.meta
├── testframework
│ ├── localizationForiOS
│ │ ├── ko.lproj
│ │ │ ├── InfoPlist.strings
│ │ │ └── InfoPlist.strings.meta
│ │ ├── ja.lproj
│ │ │ ├── InfoPlist.strings
│ │ │ └── InfoPlist.strings.meta
│ │ ├── zh-Hans.lproj
│ │ │ ├── InfoPlist.strings
│ │ │ └── InfoPlist.strings.meta
│ │ ├── zh-Hant.lproj
│ │ │ ├── InfoPlist.strings
│ │ │ └── InfoPlist.strings.meta
│ │ ├── en.lproj
│ │ │ ├── InfoPlist.strings
│ │ │ └── InfoPlist.strings.meta
│ │ ├── en.lproj.meta
│ │ ├── ja.lproj.meta
│ │ ├── ko.lproj.meta
│ │ ├── zh-Hans.lproj.meta
│ │ └── zh-Hant.lproj.meta
│ └── localizationForiOS.meta
├── Editor.meta
├── Scenes.meta
├── Scenes
│ ├── SampleScene.unity.meta
│ └── SampleScene.unity
├── NativeLocale.meta
├── Resources.meta
├── testframework.meta
└── Editor
│ ├── Xcode.meta
│ ├── Xcode
│ ├── PBX.meta
│ ├── JsonParser.cs.meta
│ ├── PBX
│ │ ├── Lexer.cs.meta
│ │ ├── Objects.cs.meta
│ │ ├── Parser.cs.meta
│ │ ├── Utils.cs.meta
│ │ ├── Elements.cs.meta
│ │ ├── Sections.cs.meta
│ │ ├── Serializer.cs.meta
│ │ ├── Elements.cs
│ │ ├── Sections.cs
│ │ ├── Parser.cs
│ │ ├── Lexer.cs
│ │ ├── Serializer.cs
│ │ └── Utils.cs
│ ├── PBXPath.cs.meta
│ ├── PBXProject.cs.meta
│ ├── PlistParser.cs.meta
│ ├── AssetCatalog.cs.meta
│ ├── PBXProjectData.cs.meta
│ ├── PBXCapabilityType.cs.meta
│ ├── PBXProjectExtensions.cs.meta
│ ├── ProjectCapabilityManager.cs.meta
│ ├── PBXPath.cs
│ ├── PBXCapabilityType.cs
│ ├── JsonParser.cs
│ ├── PlistParser.cs
│ ├── PBXProjectExtensions.cs
│ └── ProjectCapabilityManager.cs
│ ├── LocalizeName.cs.meta
│ ├── PostProcess.cs.meta
│ ├── PostProcess.cs
│ └── LocalizeName.cs
├── ProjectSettings
├── ProjectVersion.txt
├── ClusterInputManager.asset
├── NetworkManager.asset
├── XRSettings.asset
├── VersionControlSettings.asset
├── TimeManager.asset
├── EditorBuildSettings.asset
├── VFXManager.asset
├── AudioManager.asset
├── TagManager.asset
├── EditorSettings.asset
├── PresetManager.asset
├── UnityConnectSettings.asset
├── PackageManagerSettings.asset
├── DynamicsManager.asset
├── Physics2DSettings.asset
├── NavMeshAreas.asset
├── GraphicsSettings.asset
├── QualitySettings.asset
├── InputManager.asset
└── ProjectSettings.asset
├── .idea
└── .idea.UnityiOSLocalization
│ └── .idea
│ ├── encodings.xml
│ ├── vcs.xml
│ ├── indexLayout.xml
│ └── .gitignore
├── README.md
├── .gitignore
└── Packages
├── manifest.json
└── packages-lock.json
/Assets/Resources/BillingMode.json:
--------------------------------------------------------------------------------
1 | {"androidStore":"GooglePlay"}
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/ko.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | "CFBundleDisplayName" = "숲속농장";
2 |
3 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/ja.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | "CFBundleDisplayName" = "マイリトルファーム";
2 |
3 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/zh-Hans.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | "CFBundleDisplayName" = "快乐农场";
2 |
3 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/zh-Hant.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | "CFBundleDisplayName" = "快樂農場";
2 |
3 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | "CFBundleDisplayName" = "Happy Ranch";
2 |
3 |
--------------------------------------------------------------------------------
/ProjectSettings/ProjectVersion.txt:
--------------------------------------------------------------------------------
1 | m_EditorVersion: 2020.3.15f2
2 | m_EditorVersionWithRevision: 2020.3.15f2 (6cf78cb77498)
3 |
--------------------------------------------------------------------------------
/ProjectSettings/ClusterInputManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!236 &1
4 | ClusterInputManager:
5 | m_ObjectHideFlags: 0
6 | m_Inputs: []
7 |
--------------------------------------------------------------------------------
/Assets/Editor.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d1995b76918c543638277358608da8b3
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Scenes.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 84c01cd07fe3246a8a64fb1dac523399
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Scenes/SampleScene.unity.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8dcefbff236db468ea094005da029440
3 | DefaultImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/Assets/NativeLocale.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 770e3cb26c0e841bd9e1a2435f8770ba
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Resources.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 69926427253e341ff95da65f923e035f
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Resources/BillingMode.json.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 3058f497f2ad644e899b2935b4c44845
3 | TextScriptImporter:
4 | externalObjects: {}
5 | userData:
6 | assetBundleName:
7 | assetBundleVariant:
8 |
--------------------------------------------------------------------------------
/ProjectSettings/NetworkManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!149 &1
4 | NetworkManager:
5 | m_ObjectHideFlags: 0
6 | m_DebugLevel: 0
7 | m_Sendrate: 15
8 | m_AssetToPrefab: {}
9 |
--------------------------------------------------------------------------------
/.idea/.idea.UnityiOSLocalization/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Assets/testframework.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 1a7ef88d569d0490584770789d8d8ab4
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/ProjectSettings/XRSettings.asset:
--------------------------------------------------------------------------------
1 | {
2 | "m_SettingKeys": [
3 | "VR Device Disabled",
4 | "VR Device User Alert"
5 | ],
6 | "m_SettingValues": [
7 | "False",
8 | "False"
9 | ]
10 | }
--------------------------------------------------------------------------------
/.idea/.idea.UnityiOSLocalization/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 4ddbc2e96d7e843b1a69cd158f916b07
3 | folderAsset: yes
4 | DefaultImporter:
5 | externalObjects: {}
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 670d932844d474051b5ad5960f043d7c
3 | folderAsset: yes
4 | timeCreated: 1535613234
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBX.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7625017be5ff149a6b0f20ee645ce11e
3 | folderAsset: yes
4 | timeCreated: 1496741689
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/ProjectSettings/VersionControlSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!890905787 &1
4 | VersionControlSettings:
5 | m_ObjectHideFlags: 0
6 | m_Mode: Visible Meta Files
7 | m_CollabEditorSettings:
8 | inProgressEnabled: 1
9 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/en.lproj/InfoPlist.strings.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ab1681df1e38c46e3aff627f7a524e0f
3 | timeCreated: 1535100536
4 | licenseType: Free
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/ja.lproj/InfoPlist.strings.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 81e29d34a607f4de4af35be759402d05
3 | timeCreated: 1535100536
4 | licenseType: Free
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/ko.lproj/InfoPlist.strings.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c854fdf2e801941e3891cbf5eb81fa5c
3 | timeCreated: 1535100536
4 | licenseType: Free
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/ProjectSettings/TimeManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!5 &1
4 | TimeManager:
5 | m_ObjectHideFlags: 0
6 | Fixed Timestep: 0.02
7 | Maximum Allowed Timestep: 0.1
8 | m_TimeScale: 1
9 | Maximum Particle Timestep: 0.03
10 |
--------------------------------------------------------------------------------
/.idea/.idea.UnityiOSLocalization/.idea/indexLayout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/zh-Hans.lproj/InfoPlist.strings.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 6bf01c3fb24924bca822641e520fee19
3 | timeCreated: 1535100536
4 | licenseType: Free
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/zh-Hant.lproj/InfoPlist.strings.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: acb6c30553f25469297dd903e332d689
3 | timeCreated: 1535100536
4 | licenseType: Free
5 | DefaultImporter:
6 | userData:
7 | assetBundleName:
8 | assetBundleVariant:
9 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/en.lproj.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: d16819a599a6a414da6041632b0b304b
3 | folderAsset: yes
4 | timeCreated: 1535100536
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/ja.lproj.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7f56c6844430b44479a48c9a5ce3aa75
3 | folderAsset: yes
4 | timeCreated: 1535100536
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/ko.lproj.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5daa403c129724ebea32621f4ea7989d
3 | folderAsset: yes
4 | timeCreated: 1535100536
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/zh-Hans.lproj.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: ed75300803a644304adb37d6b89ba0d1
3 | folderAsset: yes
4 | timeCreated: 1535100536
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Assets/testframework/localizationForiOS/zh-Hant.lproj.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 7630b4e7b9c204e69b5725a0d8f781a4
3 | folderAsset: yes
4 | timeCreated: 1535100536
5 | licenseType: Free
6 | DefaultImporter:
7 | userData:
8 | assetBundleName:
9 | assetBundleVariant:
10 |
--------------------------------------------------------------------------------
/Assets/Editor/LocalizeName.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: f71f959e449a34e318f18ef8ff951f39
3 | timeCreated: 1535600010
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/PostProcess.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 99cef3a16ce8b4417a1e8bf36010cd64
3 | timeCreated: 1535626135
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/ProjectSettings/EditorBuildSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1045 &1
4 | EditorBuildSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | m_Scenes:
8 | - enabled: 1
9 | path: Assets/Scenes/SampleScene.unity
10 | guid: 8dcefbff236db468ea094005da029440
11 | m_configObjects: {}
12 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/JsonParser.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 052ac8a8c9ae3466f94f7b3b6c5b61af
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBX/Lexer.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 9766f6c4eb5ef42f99c0d5f86e34ba84
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBX/Objects.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 67cf10cf994604c719f706525399f867
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBX/Parser.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5ce5a244bc4e04a668ab097db4456665
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBX/Utils.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 8eafbccf2ded14760af588ffcb1ca0f5
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBXPath.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 57be5de7dcd844631b3e835186497c25
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBXProject.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 5923416dbf32e48428afbeee2b4eb48e
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PlistParser.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: c2ed9743fe9634c808ea1dc01c20e01e
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/ProjectSettings/VFXManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!937362698 &1
4 | VFXManager:
5 | m_ObjectHideFlags: 0
6 | m_IndirectShader: {fileID: 0}
7 | m_CopyBufferShader: {fileID: 0}
8 | m_SortShader: {fileID: 0}
9 | m_RenderPipeSettingsPath:
10 | m_FixedTimeStep: 0.016666668
11 | m_MaxDeltaTime: 0.05
12 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/AssetCatalog.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 46dd33873affe4e5caf86cb784bd831a
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBX/Elements.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 83cffec4be0e045258109e9714cdaa5f
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBX/Sections.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 60639b138b83f4ce9b2448c38a6ba285
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBX/Serializer.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: afe8316bf614347729fac3466d7c77f2
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBXProjectData.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 54c86bc46b87645c78e5b211a0eeada5
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBXCapabilityType.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 71f2dd6273cda4741b9b3bac41a9b765
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBXProjectExtensions.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: b84f17869f54f4d7a952c9f63e5744d6
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/ProjectCapabilityManager.cs.meta:
--------------------------------------------------------------------------------
1 | fileFormatVersion: 2
2 | guid: 2bfeebf480ee141979c8981b78c0a488
3 | timeCreated: 1496741691
4 | licenseType: Free
5 | MonoImporter:
6 | serializedVersion: 2
7 | defaultReferences: []
8 | executionOrder: 0
9 | icon: {instanceID: 0}
10 | userData:
11 | assetBundleName:
12 | assetBundleVariant:
13 |
--------------------------------------------------------------------------------
/.idea/.idea.UnityiOSLocalization/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Rider ignored files
5 | /contentModel.xml
6 | /modules.xml
7 | /.idea.UnityiOSLocalization.iml
8 | /projectSettingsUpdater.xml
9 | # Datasource local storage ignored files
10 | /dataSources/
11 | /dataSources.local.xml
12 | # Editor-based HTTP Client requests
13 | /httpRequests/
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # UnityiOSLocalization sample project
2 |
3 | sample project for iOS localizable works with onPostProcessBuild API and Unity XcodeAPI
4 |
5 |
6 |
7 | Refs
8 | - https://github.com/zeyangl/UnityAppNameLocalizationForIOS
9 | - https://bitbucket.org/Unity-Technologies/xcodeapi/src/stable/
10 | - https://docs.unity3d.com/kr/2017.4/ScriptReference/Build.IPostprocessBuild.OnPostprocessBuild.html
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ProjectSettings/AudioManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!11 &1
4 | AudioManager:
5 | m_ObjectHideFlags: 0
6 | m_Volume: 1
7 | Rolloff Scale: 1
8 | Doppler Factor: 1
9 | Default Speaker Mode: 2
10 | m_SampleRate: 0
11 | m_DSPBufferSize: 1024
12 | m_VirtualVoiceCount: 512
13 | m_RealVoiceCount: 32
14 | m_SpatializerPlugin:
15 | m_AmbisonicDecoderPlugin:
16 | m_DisableAudio: 0
17 | m_VirtualizeEffects: 1
18 |
--------------------------------------------------------------------------------
/ProjectSettings/TagManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!78 &1
4 | TagManager:
5 | serializedVersion: 2
6 | tags: []
7 | layers:
8 | - Default
9 | - TransparentFX
10 | - Ignore Raycast
11 | -
12 | - Water
13 | - UI
14 | -
15 | -
16 | - PostProcessing
17 | -
18 | -
19 | -
20 | -
21 | -
22 | -
23 | -
24 | -
25 | -
26 | -
27 | -
28 | -
29 | -
30 | -
31 | -
32 | -
33 | -
34 | -
35 | -
36 | -
37 | -
38 | -
39 | -
40 | m_SortingLayers:
41 | - name: Default
42 | uniqueID: 0
43 | locked: 0
44 |
--------------------------------------------------------------------------------
/ProjectSettings/EditorSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!159 &1
4 | EditorSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 7
7 | m_ExternalVersionControlSupport: Visible Meta Files
8 | m_SerializationMode: 2
9 | m_LineEndingsForNewScripts: 2
10 | m_DefaultBehaviorMode: 0
11 | m_PrefabRegularEnvironment: {fileID: 0}
12 | m_PrefabUIEnvironment: {fileID: 0}
13 | m_SpritePackerMode: 0
14 | m_SpritePackerPaddingPower: 1
15 | m_EtcTextureCompressorBehavior: 1
16 | m_EtcTextureFastCompressor: 1
17 | m_EtcTextureNormalCompressor: 2
18 | m_EtcTextureBestCompressor: 4
19 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef
20 | m_ProjectGenerationRootNamespace:
21 | m_CollabEditorSettings:
22 | inProgressEnabled: 1
23 | m_EnableTextureStreamingInPlayMode: 1
24 |
--------------------------------------------------------------------------------
/ProjectSettings/PresetManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!1386491679 &1
4 | PresetManager:
5 | m_ObjectHideFlags: 0
6 | m_DefaultList:
7 | - type:
8 | m_NativeTypeID: 108
9 | m_ManagedTypePPtr: {fileID: 0}
10 | m_ManagedTypeFallback:
11 | defaultPresets:
12 | - m_Preset: {fileID: 2655988077585873504, guid: c1cf8506f04ef2c4a88b64b6c4202eea,
13 | type: 2}
14 | - type:
15 | m_NativeTypeID: 1020
16 | m_ManagedTypePPtr: {fileID: 0}
17 | m_ManagedTypeFallback:
18 | defaultPresets:
19 | - m_Preset: {fileID: 2655988077585873504, guid: 0cd792cc87e492d43b4e95b205fc5cc6,
20 | type: 2}
21 | - type:
22 | m_NativeTypeID: 1006
23 | m_ManagedTypePPtr: {fileID: 0}
24 | m_ManagedTypeFallback:
25 | defaultPresets:
26 | - m_Preset: {fileID: 2655988077585873504, guid: 7a99f8aa944efe94cb9bd74562b7d5f9,
27 | type: 2}
28 |
--------------------------------------------------------------------------------
/ProjectSettings/UnityConnectSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!310 &1
4 | UnityConnectSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 1
7 | m_Enabled: 0
8 | m_TestMode: 0
9 | m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events
10 | m_EventUrl: https://cdp.cloud.unity3d.com/v1/events
11 | m_ConfigUrl: https://config.uca.cloud.unity3d.com
12 | m_DashboardUrl: https://dashboard.unity3d.com
13 | m_TestInitMode: 0
14 | CrashReportingSettings:
15 | m_EventUrl: https://perf-events.cloud.unity3d.com
16 | m_Enabled: 0
17 | m_LogBufferSize: 10
18 | m_CaptureEditorExceptions: 1
19 | UnityPurchasingSettings:
20 | m_Enabled: 0
21 | m_TestMode: 0
22 | UnityAnalyticsSettings:
23 | m_Enabled: 0
24 | m_TestMode: 0
25 | m_InitializeOnStartup: 1
26 | UnityAdsSettings:
27 | m_Enabled: 0
28 | m_InitializeOnStartup: 1
29 | m_TestMode: 0
30 | m_IosGameId:
31 | m_AndroidGameId:
32 | m_GameIds: {}
33 | m_GameId:
34 | PerformanceReportingSettings:
35 | m_Enabled: 0
36 |
--------------------------------------------------------------------------------
/ProjectSettings/PackageManagerSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!114 &1
4 | MonoBehaviour:
5 | m_ObjectHideFlags: 61
6 | m_CorrespondingSourceObject: {fileID: 0}
7 | m_PrefabInstance: {fileID: 0}
8 | m_PrefabAsset: {fileID: 0}
9 | m_GameObject: {fileID: 0}
10 | m_Enabled: 1
11 | m_EditorHideFlags: 0
12 | m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0}
13 | m_Name:
14 | m_EditorClassIdentifier:
15 | m_EnablePreviewPackages: 0
16 | m_EnablePackageDependencies: 0
17 | m_AdvancedSettingsExpanded: 1
18 | m_ScopedRegistriesSettingsExpanded: 1
19 | oneTimeWarningShown: 0
20 | m_Registries:
21 | - m_Id: main
22 | m_Name:
23 | m_Url: https://packages.unity.com
24 | m_Scopes: []
25 | m_IsDefault: 1
26 | m_Capabilities: 7
27 | m_UserSelectedRegistryName:
28 | m_UserAddingNewScopedRegistry: 0
29 | m_RegistryInfoDraft:
30 | m_ErrorMessage:
31 | m_Original:
32 | m_Id:
33 | m_Name:
34 | m_Url:
35 | m_Scopes: []
36 | m_IsDefault: 0
37 | m_Capabilities: 0
38 | m_Modified: 0
39 | m_Name:
40 | m_Url:
41 | m_Scopes:
42 | -
43 | m_SelectedScopeIndex: 0
44 |
--------------------------------------------------------------------------------
/ProjectSettings/DynamicsManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!55 &1
4 | PhysicsManager:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 8
7 | m_Gravity: {x: 0, y: -9.81, z: 0}
8 | m_DefaultMaterial: {fileID: 0}
9 | m_BounceThreshold: 2
10 | m_SleepThreshold: 0.005
11 | m_DefaultContactOffset: 0.01
12 | m_DefaultSolverIterations: 6
13 | m_DefaultSolverVelocityIterations: 1
14 | m_QueriesHitBackfaces: 0
15 | m_QueriesHitTriggers: 1
16 | m_EnableAdaptiveForce: 0
17 | m_ClothInterCollisionDistance: 0
18 | m_ClothInterCollisionStiffness: 0
19 | m_ContactsGeneration: 1
20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
21 | m_AutoSimulation: 1
22 | m_AutoSyncTransforms: 0
23 | m_ReuseCollisionCallbacks: 1
24 | m_ClothInterCollisionSettingsToggle: 0
25 | m_ContactPairsMode: 0
26 | m_BroadphaseType: 0
27 | m_WorldBounds:
28 | m_Center: {x: 0, y: 0, z: 0}
29 | m_Extent: {x: 250, y: 250, z: 250}
30 | m_WorldSubdivisions: 8
31 |
--------------------------------------------------------------------------------
/Assets/Editor/PostProcess.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 | using UnityEditor;
5 | using UnityEditor.Callbacks;
6 | using Strings;
7 | using System.IO;
8 | using UnityEditor.iOS.Xcode;
9 |
10 | namespace Strings
11 | {
12 | public class PostProcess : MonoBehaviour
13 | {
14 | private const string ADMOB_SETTING = "GADIsAdManagerApp";
15 |
16 | [PostProcessBuildAttribute(199999)]
17 | public static void OnPostProcessBuild(BuildTarget target, string path)
18 | {
19 | if (target == BuildTarget.iOS)
20 | {
21 | OnIOSBuild(target, path);
22 | }
23 | }
24 |
25 | private static void OnIOSBuild(BuildTarget target, string path)
26 | {
27 | LocalizeName.AddLocalizedStringsIOS(path, Path.Combine(Application.dataPath, "testframework/localizationForiOS"));
28 |
29 | string infoPlistPath = path + "/Info.plist";
30 |
31 | PlistDocument plistDoc = new PlistDocument();
32 | plistDoc.ReadFromFile(infoPlistPath);
33 | if (plistDoc.root != null) {
34 | plistDoc.root.SetBoolean(ADMOB_SETTING, true);
35 | plistDoc.WriteToFile(infoPlistPath);
36 | }
37 | else {
38 | Debug.LogError("ERROR: Can't open " + infoPlistPath);
39 | }
40 | }
41 | }
42 | }
43 |
44 |
45 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # This .gitignore file should be placed at the root of your Unity project directory
2 | #
3 | # Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore
4 | #
5 | /[Ll]ibrary/*
6 | /[Tt]emp/
7 | /[Oo]bj/
8 | /[Bb]uild/
9 | /[Bb]uilds/
10 | /[Ll]ogs/
11 | /[Uu]ser[Ss]ettings/
12 |
13 |
14 | # MemoryCaptures can get excessive in size.
15 | # They also could contain extremely sensitive data
16 | /[Mm]emoryCaptures/
17 |
18 | # Recordings can get excessive in size
19 | /[Rr]ecordings/
20 |
21 | # Uncomment this line if you wish to ignore the asset store tools plugin
22 | # /[Aa]ssets/AssetStoreTools*
23 |
24 | # Autogenerated Jetbrains Rider plugin
25 | /[Aa]ssets/Plugins/Editor/JetBrains*
26 |
27 | # Visual Studio cache directory
28 | .vs/
29 |
30 | # Gradle cache directory
31 | .gradle/
32 |
33 | # Autogenerated VS/MD/Consulo solution and project files
34 | ExportedObj/
35 | .consulo/
36 | *.csproj
37 | *.unityproj
38 | *.sln
39 | *.suo
40 | *.tmp
41 | *.user
42 | *.userprefs
43 | *.pidb
44 | *.booproj
45 | *.svd
46 | *.pdb
47 | *.mdb
48 | *.opendb
49 | *.VC.db
50 |
51 | # Unity3D generated meta files
52 | *.pidb.meta
53 | *.pdb.meta
54 | *.mdb.meta
55 |
56 | # Unity3D generated file on crash reports
57 | sysinfo.txt
58 |
59 | # Builds
60 | *.apk
61 | *.aab
62 | *.unitypackage
63 | *.app
64 |
65 | # Crashlytics generated file
66 | crashlytics-build.properties
67 |
68 | # Packed Addressables
69 | /[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin*
70 |
71 | # Temporary auto-generated Android Assets
72 | /[Aa]ssets/[Ss]treamingAssets/aa.meta
73 | /[Aa]ssets/[Ss]treamingAssets/aa/*
--------------------------------------------------------------------------------
/ProjectSettings/Physics2DSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!19 &1
4 | Physics2DSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 4
7 | m_Gravity: {x: 0, y: -9.81}
8 | m_DefaultMaterial: {fileID: 0}
9 | m_VelocityIterations: 8
10 | m_PositionIterations: 3
11 | m_VelocityThreshold: 1
12 | m_MaxLinearCorrection: 0.2
13 | m_MaxAngularCorrection: 8
14 | m_MaxTranslationSpeed: 100
15 | m_MaxRotationSpeed: 360
16 | m_BaumgarteScale: 0.2
17 | m_BaumgarteTimeOfImpactScale: 0.75
18 | m_TimeToSleep: 0.5
19 | m_LinearSleepTolerance: 0.01
20 | m_AngularSleepTolerance: 2
21 | m_DefaultContactOffset: 0.01
22 | m_AutoSimulation: 1
23 | m_QueriesHitTriggers: 1
24 | m_QueriesStartInColliders: 1
25 | m_ChangeStopsCallbacks: 0
26 | m_CallbacksOnDisable: 1
27 | m_ReuseCollisionCallbacks: 1
28 | m_AutoSyncTransforms: 0
29 | m_AlwaysShowColliders: 0
30 | m_ShowColliderSleep: 1
31 | m_ShowColliderContacts: 0
32 | m_ShowColliderAABB: 0
33 | m_ContactArrowScale: 0.2
34 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412}
35 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432}
36 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745}
37 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804}
38 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
39 |
--------------------------------------------------------------------------------
/ProjectSettings/NavMeshAreas.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!126 &1
4 | NavMeshProjectSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | areas:
8 | - name: Walkable
9 | cost: 1
10 | - name: Not Walkable
11 | cost: 1
12 | - name: Jump
13 | cost: 2
14 | - name:
15 | cost: 1
16 | - name:
17 | cost: 1
18 | - name:
19 | cost: 1
20 | - name:
21 | cost: 1
22 | - name:
23 | cost: 1
24 | - name:
25 | cost: 1
26 | - name:
27 | cost: 1
28 | - name:
29 | cost: 1
30 | - name:
31 | cost: 1
32 | - name:
33 | cost: 1
34 | - name:
35 | cost: 1
36 | - name:
37 | cost: 1
38 | - name:
39 | cost: 1
40 | - name:
41 | cost: 1
42 | - name:
43 | cost: 1
44 | - name:
45 | cost: 1
46 | - name:
47 | cost: 1
48 | - name:
49 | cost: 1
50 | - name:
51 | cost: 1
52 | - name:
53 | cost: 1
54 | - name:
55 | cost: 1
56 | - name:
57 | cost: 1
58 | - name:
59 | cost: 1
60 | - name:
61 | cost: 1
62 | - name:
63 | cost: 1
64 | - name:
65 | cost: 1
66 | - name:
67 | cost: 1
68 | - name:
69 | cost: 1
70 | - name:
71 | cost: 1
72 | m_LastAgentTypeID: -887442657
73 | m_Settings:
74 | - serializedVersion: 2
75 | agentTypeID: 0
76 | agentRadius: 0.5
77 | agentHeight: 2
78 | agentSlope: 45
79 | agentClimb: 0.75
80 | ledgeDropHeight: 0
81 | maxJumpAcrossDistance: 0
82 | minRegionArea: 2
83 | manualCellSize: 0
84 | cellSize: 0.16666667
85 | manualTileSize: 0
86 | tileSize: 256
87 | accuratePlacement: 0
88 | debug:
89 | m_Flags: 0
90 | m_SettingNames:
91 | - Humanoid
92 |
--------------------------------------------------------------------------------
/Packages/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "com.unity.2d.sprite": "1.0.0",
4 | "com.unity.2d.tilemap": "1.0.0",
5 | "com.unity.ads": "3.7.1",
6 | "com.unity.analytics": "3.5.3",
7 | "com.unity.collab-proxy": "1.7.1",
8 | "com.unity.ide.rider": "2.0.7",
9 | "com.unity.ide.visualstudio": "2.0.9",
10 | "com.unity.ide.vscode": "1.2.3",
11 | "com.unity.purchasing": "3.2.2",
12 | "com.unity.test-framework": "1.1.27",
13 | "com.unity.textmeshpro": "3.0.6",
14 | "com.unity.timeline": "1.4.8",
15 | "com.unity.ugui": "1.0.0",
16 | "com.unity.xr.legacyinputhelpers": "2.1.7",
17 | "com.unity.modules.ai": "1.0.0",
18 | "com.unity.modules.androidjni": "1.0.0",
19 | "com.unity.modules.animation": "1.0.0",
20 | "com.unity.modules.assetbundle": "1.0.0",
21 | "com.unity.modules.audio": "1.0.0",
22 | "com.unity.modules.cloth": "1.0.0",
23 | "com.unity.modules.director": "1.0.0",
24 | "com.unity.modules.imageconversion": "1.0.0",
25 | "com.unity.modules.imgui": "1.0.0",
26 | "com.unity.modules.jsonserialize": "1.0.0",
27 | "com.unity.modules.particlesystem": "1.0.0",
28 | "com.unity.modules.physics": "1.0.0",
29 | "com.unity.modules.physics2d": "1.0.0",
30 | "com.unity.modules.screencapture": "1.0.0",
31 | "com.unity.modules.terrain": "1.0.0",
32 | "com.unity.modules.terrainphysics": "1.0.0",
33 | "com.unity.modules.tilemap": "1.0.0",
34 | "com.unity.modules.ui": "1.0.0",
35 | "com.unity.modules.uielements": "1.0.0",
36 | "com.unity.modules.umbra": "1.0.0",
37 | "com.unity.modules.unityanalytics": "1.0.0",
38 | "com.unity.modules.unitywebrequest": "1.0.0",
39 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0",
40 | "com.unity.modules.unitywebrequestaudio": "1.0.0",
41 | "com.unity.modules.unitywebrequesttexture": "1.0.0",
42 | "com.unity.modules.unitywebrequestwww": "1.0.0",
43 | "com.unity.modules.vehicles": "1.0.0",
44 | "com.unity.modules.video": "1.0.0",
45 | "com.unity.modules.vr": "1.0.0",
46 | "com.unity.modules.wind": "1.0.0",
47 | "com.unity.modules.xr": "1.0.0"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/ProjectSettings/GraphicsSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!30 &1
4 | GraphicsSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 12
7 | m_Deferred:
8 | m_Mode: 1
9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0}
10 | m_DeferredReflections:
11 | m_Mode: 1
12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0}
13 | m_ScreenSpaceShadows:
14 | m_Mode: 1
15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0}
16 | m_LegacyDeferred:
17 | m_Mode: 1
18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0}
19 | m_DepthNormals:
20 | m_Mode: 1
21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0}
22 | m_MotionVectors:
23 | m_Mode: 1
24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0}
25 | m_LightHalo:
26 | m_Mode: 1
27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0}
28 | m_LensFlare:
29 | m_Mode: 1
30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0}
31 | m_AlwaysIncludedShaders:
32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}
33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0}
34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0}
35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0}
36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
38 | - {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0}
39 | - {fileID: 16000, guid: 0000000000000000f000000000000000, type: 0}
40 | - {fileID: 17000, guid: 0000000000000000f000000000000000, type: 0}
41 | m_PreloadedShaders: []
42 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000,
43 | type: 0}
44 | m_CustomRenderPipeline: {fileID: 0}
45 | m_TransparencySortMode: 0
46 | m_TransparencySortAxis: {x: 0, y: 0, z: 1}
47 | m_DefaultRenderingPath: 1
48 | m_DefaultMobileRenderingPath: 1
49 | m_TierSettings: []
50 | m_LightmapStripping: 0
51 | m_FogStripping: 0
52 | m_InstancingStripping: 0
53 | m_LightmapKeepPlain: 1
54 | m_LightmapKeepDirCombined: 1
55 | m_LightmapKeepDynamicPlain: 1
56 | m_LightmapKeepDynamicDirCombined: 1
57 | m_LightmapKeepShadowMask: 1
58 | m_LightmapKeepSubtractive: 1
59 | m_FogKeepLinear: 1
60 | m_FogKeepExp: 1
61 | m_FogKeepExp2: 1
62 | m_AlbedoSwatchInfos: []
63 | m_LightsUseLinearIntensity: 0
64 | m_LightsUseColorTemperature: 0
65 | m_LogWhenShaderIsCompiled: 0
66 |
--------------------------------------------------------------------------------
/Assets/Editor/LocalizeName.cs:
--------------------------------------------------------------------------------
1 | using System.Collections;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 | using UnityEditor;
5 | using System.IO;
6 | using Strings.iOS.Xcode;
7 |
8 | namespace Strings
9 | {
10 | public class LocalizeName
11 | {
12 | public static void AddLocalizedStringsIOS(string projectPath, string localizedDirectoryPath)
13 | {
14 | DirectoryInfo dir = new DirectoryInfo(localizedDirectoryPath);
15 | if (!dir.Exists)
16 | return;
17 |
18 | List locales = new List();
19 | var localeDirs = dir.GetDirectories("*.lproj", SearchOption.TopDirectoryOnly);
20 |
21 | foreach (var sub in localeDirs)
22 | locales.Add(Path.GetFileNameWithoutExtension(sub.Name));
23 |
24 | AddLocalizedStringsIOS(projectPath, localizedDirectoryPath, locales);
25 | }
26 |
27 | public static void AddLocalizedStringsIOS(string projectPath, string localizedDirectoryPath, List validLocales)
28 | {
29 | string projPath = projectPath + "/Unity-iPhone.xcodeproj/project.pbxproj";
30 | PBXProject proj = new PBXProject();
31 | proj.ReadFromFile(projPath);
32 | proj.ClearVariantGroupEntries("InfoPlist.strings");
33 | foreach (var locale in validLocales)
34 | {
35 | string src = Path.Combine(localizedDirectoryPath, locale + ".lproj");
36 | DirectoryCopy(src, Path.Combine(projectPath, locale + ".lproj"));
37 |
38 | string fileRelatvePath = string.Format("{0}.lproj/InfoPlist.strings", locale);
39 | proj.AddLocalization("InfoPlist.strings", locale, fileRelatvePath);
40 | }
41 |
42 | proj.WriteToFile(projPath);
43 | }
44 |
45 |
46 | private static void DirectoryCopy(string sourceDirName, string destDirName)
47 | {
48 | DirectoryInfo dir = new DirectoryInfo(sourceDirName);
49 |
50 | if (!dir.Exists)
51 | return;
52 |
53 | if (!Directory.Exists(destDirName))
54 | {
55 | Directory.CreateDirectory(destDirName);
56 | }
57 |
58 | FileInfo[] files = dir.GetFiles();
59 |
60 | foreach (FileInfo file in files)
61 | {
62 | if (file.FullName.EndsWith(".meta"))
63 | continue;
64 |
65 | string temppath = Path.Combine(destDirName, file.Name);
66 | file.CopyTo(temppath, false);
67 | }
68 |
69 | DirectoryInfo[] dirs = dir.GetDirectories();
70 | foreach (DirectoryInfo subdir in dirs)
71 | {
72 | string temppath = Path.Combine(destDirName, subdir.Name);
73 | DirectoryCopy(subdir.FullName, temppath);
74 | }
75 | }
76 | }
77 | }
78 |
79 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBX/Elements.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Collections;
3 | using System;
4 |
5 |
6 | namespace Strings.iOS.Xcode.PBX
7 | {
8 |
9 | class PBXElement
10 | {
11 | protected PBXElement() {}
12 |
13 | // convenience methods
14 | public string AsString() { return ((PBXElementString)this).value; }
15 | public PBXElementArray AsArray() { return (PBXElementArray)this; }
16 | public PBXElementDict AsDict() { return (PBXElementDict)this; }
17 |
18 | public PBXElement this[string key]
19 | {
20 | get { return AsDict()[key]; }
21 | set { AsDict()[key] = value; }
22 | }
23 | }
24 |
25 | class PBXElementString : PBXElement
26 | {
27 | public PBXElementString(string v) { value = v; }
28 |
29 | public string value;
30 | }
31 |
32 | class PBXElementDict : PBXElement
33 | {
34 | public PBXElementDict() : base() {}
35 |
36 | private Dictionary m_PrivateValue = new Dictionary();
37 | public IDictionary values { get { return m_PrivateValue; }}
38 |
39 | new public PBXElement this[string key]
40 | {
41 | get {
42 | if (values.ContainsKey(key))
43 | return values[key];
44 | return null;
45 | }
46 | set { this.values[key] = value; }
47 | }
48 |
49 | public bool Contains(string key)
50 | {
51 | return values.ContainsKey(key);
52 | }
53 |
54 | public void Remove(string key)
55 | {
56 | values.Remove(key);
57 | }
58 |
59 | public void SetString(string key, string val)
60 | {
61 | values[key] = new PBXElementString(val);
62 | }
63 |
64 | public PBXElementArray CreateArray(string key)
65 | {
66 | var v = new PBXElementArray();
67 | values[key] = v;
68 | return v;
69 | }
70 |
71 | public PBXElementDict CreateDict(string key)
72 | {
73 | var v = new PBXElementDict();
74 | values[key] = v;
75 | return v;
76 | }
77 | }
78 |
79 | class PBXElementArray : PBXElement
80 | {
81 | public PBXElementArray() : base() {}
82 | public List values = new List();
83 |
84 | // convenience methods
85 | public void AddString(string val)
86 | {
87 | values.Add(new PBXElementString(val));
88 | }
89 |
90 | public PBXElementArray AddArray()
91 | {
92 | var v = new PBXElementArray();
93 | values.Add(v);
94 | return v;
95 | }
96 |
97 | public PBXElementDict AddDict()
98 | {
99 | var v = new PBXElementDict();
100 | values.Add(v);
101 | return v;
102 | }
103 | }
104 |
105 | } // namespace UnityEditor.iOS.Xcode
106 |
107 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBXPath.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Text.RegularExpressions;
5 | using System.IO;
6 |
7 | namespace Strings.iOS.Xcode
8 | {
9 | internal class PBXPath
10 | {
11 | /// Replaces '\' with '/'. We need to apply this function to all paths that come from the user
12 | /// of the API because we store paths to pbxproj and on windows we may get path with '\' slashes
13 | /// instead of '/' slashes
14 | public static string FixSlashes(string path)
15 | {
16 | if (path == null)
17 | return null;
18 | return path.Replace('\\', '/');
19 | }
20 |
21 | public static void Combine(string path1, PBXSourceTree tree1, string path2, PBXSourceTree tree2,
22 | out string resPath, out PBXSourceTree resTree)
23 | {
24 | if (tree2 == PBXSourceTree.Group)
25 | {
26 | resPath = Combine(path1, path2);
27 | resTree = tree1;
28 | return;
29 | }
30 |
31 | resPath = path2;
32 | resTree = tree2;
33 | }
34 |
35 | // Combines two paths
36 | public static string Combine(string path1, string path2)
37 | {
38 | if (path2.StartsWith("/"))
39 | return path2;
40 | if (path1.EndsWith("/"))
41 | return path1 + path2;
42 | if (path1 == "")
43 | return path2;
44 | if (path2 == "")
45 | return path1;
46 | return path1 + "/" + path2;
47 | }
48 |
49 | public static string GetDirectory(string path)
50 | {
51 | path = path.TrimEnd('/');
52 | int pos = path.LastIndexOf('/');
53 | if (pos == -1)
54 | return "";
55 | else
56 | return path.Substring(0, pos);
57 | }
58 |
59 | public static string GetCurrentDirectory()
60 | {
61 | if (Environment.OSVersion.Platform != PlatformID.MacOSX &&
62 | Environment.OSVersion.Platform != PlatformID.Unix)
63 | {
64 | throw new Exception("PBX project compatible current directory can only obtained on OSX");
65 | }
66 |
67 | string path = Directory.GetCurrentDirectory();
68 | path = FixSlashes(path);
69 | if (!IsPathRooted(path))
70 | return "/" + path;
71 | return path;
72 | }
73 |
74 | public static string GetFilename(string path)
75 | {
76 | int pos = path.LastIndexOf('/');
77 | if (pos == -1)
78 | return path;
79 | else
80 | return path.Substring(pos + 1);
81 | }
82 |
83 | public static bool IsPathRooted(string path)
84 | {
85 | if (path == null || path.Length == 0)
86 | return false;
87 | return path[0] == '/';
88 | }
89 |
90 | public static string GetFullPath(string path)
91 | {
92 | if (IsPathRooted(path))
93 | return path;
94 | else
95 | return Combine(GetCurrentDirectory(), path);
96 | }
97 |
98 | public static string[] Split(string path)
99 | {
100 | if (string.IsNullOrEmpty(path))
101 | return new string[]{};
102 | return path.Split(new[]{'/'}, StringSplitOptions.RemoveEmptyEntries);
103 | }
104 | }
105 |
106 | } // UnityEditor.iOS.Xcode
107 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBX/Sections.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Text;
5 | using System.Text.RegularExpressions;
6 | using System.IO;
7 |
8 | // Basr classes for section handling
9 |
10 | namespace Strings.iOS.Xcode.PBX
11 | {
12 |
13 | // common base
14 | internal abstract class SectionBase
15 | {
16 | public abstract void AddObject(string key, PBXElementDict value);
17 | public abstract void WriteSection(StringBuilder sb, GUIDToCommentMap comments);
18 | }
19 |
20 | // known section: contains objects that we care about
21 | internal class KnownSectionBase : SectionBase where T : PBXObjectData, new()
22 | {
23 | private Dictionary m_Entries = new Dictionary();
24 |
25 | private string m_Name;
26 |
27 | public KnownSectionBase(string sectionName)
28 | {
29 | m_Name = sectionName;
30 | }
31 |
32 | public IEnumerable> GetEntries()
33 | {
34 | return m_Entries;
35 | }
36 |
37 | public IEnumerable GetGuids()
38 | {
39 | return m_Entries.Keys;
40 | }
41 |
42 | public IEnumerable GetObjects()
43 | {
44 | return m_Entries.Values;
45 | }
46 |
47 | public override void AddObject(string key, PBXElementDict value)
48 | {
49 | T obj = new T();
50 | obj.guid = key;
51 | obj.SetPropertiesWhenSerializing(value);
52 | obj.UpdateVars();
53 | m_Entries[obj.guid] = obj;
54 | }
55 |
56 | public override void WriteSection(StringBuilder sb, GUIDToCommentMap comments)
57 | {
58 | if (m_Entries.Count == 0)
59 | return; // do not write empty sections
60 |
61 | sb.AppendFormat("\n\n/* Begin {0} section */", m_Name);
62 | var keys = new List(m_Entries.Keys);
63 | keys.Sort(StringComparer.Ordinal);
64 | foreach (string key in keys)
65 | {
66 | T obj = m_Entries[key];
67 | obj.UpdateProps();
68 | sb.Append("\n\t\t");
69 | comments.WriteStringBuilder(sb, obj.guid);
70 | sb.Append(" = ");
71 | Serializer.WriteDict(sb, obj.GetPropertiesWhenSerializing(), 2,
72 | obj.shouldCompact, obj.checker, comments);
73 | sb.Append(";");
74 | }
75 | sb.AppendFormat("\n/* End {0} section */", m_Name);
76 | }
77 |
78 | // returns null if not found
79 | public T this[string guid]
80 | {
81 | get {
82 | if (m_Entries.ContainsKey(guid))
83 | return m_Entries[guid];
84 | return null;
85 | }
86 | }
87 |
88 | public bool HasEntry(string guid)
89 | {
90 | return m_Entries.ContainsKey(guid);
91 | }
92 |
93 | public void AddEntry(T obj)
94 | {
95 | m_Entries[obj.guid] = obj;
96 | }
97 |
98 | public void RemoveEntry(string guid)
99 | {
100 | if (m_Entries.ContainsKey(guid))
101 | m_Entries.Remove(guid);
102 | }
103 | }
104 |
105 | // we assume there is only one PBXProject entry
106 | internal class PBXProjectSection : KnownSectionBase
107 | {
108 | public PBXProjectSection() : base("PBXProject")
109 | {
110 | }
111 |
112 | public PBXProjectObjectData project
113 | {
114 | get {
115 | foreach (var kv in GetEntries())
116 | return kv.Value;
117 | return null;
118 | }
119 | }
120 | }
121 |
122 | } // UnityEditor.iOS.Xcode
123 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBX/Parser.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Text.RegularExpressions;
3 | using System.IO;
4 | using System.Linq;
5 | using System;
6 |
7 |
8 | namespace Strings.iOS.Xcode.PBX
9 | {
10 |
11 | class ValueAST {}
12 |
13 | // IdentifierAST := \
14 | class IdentifierAST : ValueAST
15 | {
16 | public int value = 0; // token id
17 | }
18 |
19 | // TreeAST := '{' KeyValuePairList '}'
20 | // KeyValuePairList := KeyValuePair ',' KeyValuePairList
21 | // KeyValuePair ','
22 | // (empty)
23 | class TreeAST : ValueAST
24 | {
25 | public List values = new List();
26 | }
27 |
28 | // ListAST := '(' ValueList ')'
29 | // ValueList := ValueAST ',' ValueList
30 | // ValueAST ','
31 | // (empty)
32 | class ArrayAST : ValueAST
33 | {
34 | public List values = new List();
35 | }
36 |
37 | // KeyValueAST := IdentifierAST '=' ValueAST ';'
38 | // ValueAST := IdentifierAST | TreeAST | ListAST
39 | class KeyValueAST
40 | {
41 | public IdentifierAST key = null;
42 | public ValueAST value = null; // either IdentifierAST, TreeAST or ListAST
43 | }
44 |
45 | class Parser
46 | {
47 | TokenList tokens;
48 | int currPos;
49 |
50 | public Parser(TokenList tokens)
51 | {
52 | this.tokens = tokens;
53 | currPos = SkipComments(0);
54 | }
55 |
56 | int SkipComments(int pos)
57 | {
58 | while (pos < tokens.Count && tokens[pos].type == TokenType.Comment)
59 | {
60 | pos++;
61 | }
62 | return pos;
63 | }
64 |
65 | // returns new position
66 | int IncInternal(int pos)
67 | {
68 | if (pos >= tokens.Count)
69 | return pos;
70 | pos++;
71 |
72 | return SkipComments(pos);
73 | }
74 |
75 | // Increments current pointer if not past the end, returns previous pos
76 | int Inc()
77 | {
78 | int prev = currPos;
79 | currPos = IncInternal(currPos);
80 | return prev;
81 | }
82 |
83 | // Returns the token type of the current token
84 | TokenType Tok()
85 | {
86 | if (currPos >= tokens.Count)
87 | return TokenType.EOF;
88 | return tokens[currPos].type;
89 | }
90 |
91 | void SkipIf(TokenType type)
92 | {
93 | if (Tok() == type)
94 | Inc();
95 | }
96 |
97 | string GetErrorMsg()
98 | {
99 | return "Invalid PBX project (parsing line " + tokens[currPos].line + ")";
100 | }
101 |
102 | public IdentifierAST ParseIdentifier()
103 | {
104 | if (Tok() != TokenType.String && Tok() != TokenType.QuotedString)
105 | throw new Exception(GetErrorMsg());
106 | var ast = new IdentifierAST();
107 | ast.value = Inc();
108 | return ast;
109 | }
110 |
111 | public TreeAST ParseTree()
112 | {
113 | if (Tok() != TokenType.LBrace)
114 | throw new Exception(GetErrorMsg());
115 | Inc();
116 |
117 | var ast = new TreeAST();
118 | while (Tok() != TokenType.RBrace && Tok() != TokenType.EOF)
119 | {
120 | ast.values.Add(ParseKeyValue());
121 | }
122 | SkipIf(TokenType.RBrace);
123 | return ast;
124 | }
125 |
126 | public ArrayAST ParseList()
127 | {
128 | if (Tok() != TokenType.LParen)
129 | throw new Exception(GetErrorMsg());
130 | Inc();
131 |
132 | var ast = new ArrayAST();
133 | while (Tok() != TokenType.RParen && Tok() != TokenType.EOF)
134 | {
135 | ast.values.Add(ParseValue());
136 | SkipIf(TokenType.Comma);
137 | }
138 | SkipIf(TokenType.RParen);
139 | return ast;
140 | }
141 |
142 | // throws on error
143 | public KeyValueAST ParseKeyValue()
144 | {
145 | var ast = new KeyValueAST();
146 | ast.key = ParseIdentifier();
147 |
148 | if (Tok() != TokenType.Eq)
149 | throw new Exception(GetErrorMsg());
150 | Inc(); // skip '='
151 |
152 | ast.value = ParseValue();
153 | SkipIf(TokenType.Semicolon);
154 |
155 | return ast;
156 | }
157 |
158 | // throws on error
159 | public ValueAST ParseValue()
160 | {
161 | if (Tok() == TokenType.String || Tok() == TokenType.QuotedString)
162 | return ParseIdentifier();
163 | else if (Tok() == TokenType.LBrace)
164 | return ParseTree();
165 | else if (Tok() == TokenType.LParen)
166 | return ParseList();
167 | throw new Exception(GetErrorMsg());
168 | }
169 | }
170 |
171 | } // namespace UnityEditor.iOS.Xcode
--------------------------------------------------------------------------------
/ProjectSettings/QualitySettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!47 &1
4 | QualitySettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 5
7 | m_CurrentQuality: 4
8 | m_QualitySettings:
9 | - serializedVersion: 2
10 | name: Very Low
11 | pixelLightCount: 0
12 | shadows: 0
13 | shadowResolution: 0
14 | shadowProjection: 1
15 | shadowCascades: 1
16 | shadowDistance: 15
17 | shadowNearPlaneOffset: 3
18 | shadowCascade2Split: 0.33333334
19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
20 | shadowmaskMode: 0
21 | blendWeights: 1
22 | textureQuality: 1
23 | anisotropicTextures: 0
24 | antiAliasing: 0
25 | softParticles: 0
26 | softVegetation: 0
27 | realtimeReflectionProbes: 0
28 | billboardsFaceCameraPosition: 0
29 | vSyncCount: 0
30 | lodBias: 0.3
31 | maximumLODLevel: 0
32 | particleRaycastBudget: 4
33 | asyncUploadTimeSlice: 2
34 | asyncUploadBufferSize: 16
35 | resolutionScalingFixedDPIFactor: 1
36 | excludedTargetPlatforms: []
37 | - serializedVersion: 2
38 | name: Low
39 | pixelLightCount: 0
40 | shadows: 0
41 | shadowResolution: 0
42 | shadowProjection: 1
43 | shadowCascades: 1
44 | shadowDistance: 20
45 | shadowNearPlaneOffset: 3
46 | shadowCascade2Split: 0.33333334
47 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
48 | shadowmaskMode: 0
49 | blendWeights: 2
50 | textureQuality: 0
51 | anisotropicTextures: 0
52 | antiAliasing: 0
53 | softParticles: 0
54 | softVegetation: 0
55 | realtimeReflectionProbes: 0
56 | billboardsFaceCameraPosition: 0
57 | vSyncCount: 0
58 | lodBias: 0.4
59 | maximumLODLevel: 0
60 | particleRaycastBudget: 16
61 | asyncUploadTimeSlice: 2
62 | asyncUploadBufferSize: 16
63 | resolutionScalingFixedDPIFactor: 1
64 | excludedTargetPlatforms: []
65 | - serializedVersion: 2
66 | name: Medium
67 | pixelLightCount: 1
68 | shadows: 1
69 | shadowResolution: 0
70 | shadowProjection: 1
71 | shadowCascades: 1
72 | shadowDistance: 20
73 | shadowNearPlaneOffset: 3
74 | shadowCascade2Split: 0.33333334
75 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
76 | shadowmaskMode: 0
77 | blendWeights: 2
78 | textureQuality: 0
79 | anisotropicTextures: 1
80 | antiAliasing: 0
81 | softParticles: 0
82 | softVegetation: 0
83 | realtimeReflectionProbes: 0
84 | billboardsFaceCameraPosition: 0
85 | vSyncCount: 1
86 | lodBias: 0.7
87 | maximumLODLevel: 0
88 | particleRaycastBudget: 64
89 | asyncUploadTimeSlice: 2
90 | asyncUploadBufferSize: 16
91 | resolutionScalingFixedDPIFactor: 1
92 | excludedTargetPlatforms: []
93 | - serializedVersion: 2
94 | name: High
95 | pixelLightCount: 2
96 | shadows: 2
97 | shadowResolution: 1
98 | shadowProjection: 1
99 | shadowCascades: 2
100 | shadowDistance: 40
101 | shadowNearPlaneOffset: 3
102 | shadowCascade2Split: 0.33333334
103 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
104 | shadowmaskMode: 1
105 | blendWeights: 2
106 | textureQuality: 0
107 | anisotropicTextures: 1
108 | antiAliasing: 2
109 | softParticles: 0
110 | softVegetation: 1
111 | realtimeReflectionProbes: 1
112 | billboardsFaceCameraPosition: 1
113 | vSyncCount: 1
114 | lodBias: 1
115 | maximumLODLevel: 0
116 | particleRaycastBudget: 256
117 | asyncUploadTimeSlice: 2
118 | asyncUploadBufferSize: 16
119 | resolutionScalingFixedDPIFactor: 1
120 | excludedTargetPlatforms: []
121 | - serializedVersion: 2
122 | name: Very High
123 | pixelLightCount: 3
124 | shadows: 2
125 | shadowResolution: 2
126 | shadowProjection: 1
127 | shadowCascades: 2
128 | shadowDistance: 40
129 | shadowNearPlaneOffset: 3
130 | shadowCascade2Split: 0.33333334
131 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
132 | shadowmaskMode: 1
133 | blendWeights: 4
134 | textureQuality: 0
135 | anisotropicTextures: 1
136 | antiAliasing: 4
137 | softParticles: 1
138 | softVegetation: 1
139 | realtimeReflectionProbes: 1
140 | billboardsFaceCameraPosition: 1
141 | vSyncCount: 1
142 | lodBias: 1.5
143 | maximumLODLevel: 0
144 | particleRaycastBudget: 1024
145 | asyncUploadTimeSlice: 2
146 | asyncUploadBufferSize: 16
147 | resolutionScalingFixedDPIFactor: 1
148 | excludedTargetPlatforms: []
149 | - serializedVersion: 2
150 | name: Ultra
151 | pixelLightCount: 4
152 | shadows: 2
153 | shadowResolution: 2
154 | shadowProjection: 1
155 | shadowCascades: 4
156 | shadowDistance: 150
157 | shadowNearPlaneOffset: 3
158 | shadowCascade2Split: 0.33333334
159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
160 | shadowmaskMode: 1
161 | blendWeights: 4
162 | textureQuality: 0
163 | anisotropicTextures: 1
164 | antiAliasing: 4
165 | softParticles: 1
166 | softVegetation: 1
167 | realtimeReflectionProbes: 1
168 | billboardsFaceCameraPosition: 1
169 | vSyncCount: 1
170 | lodBias: 2
171 | maximumLODLevel: 0
172 | particleRaycastBudget: 4096
173 | asyncUploadTimeSlice: 2
174 | asyncUploadBufferSize: 16
175 | resolutionScalingFixedDPIFactor: 1
176 | excludedTargetPlatforms: []
177 | m_PerPlatformDefaultQuality:
178 | Android: 2
179 | Nintendo 3DS: 5
180 | Nintendo Switch: 5
181 | PS4: 5
182 | PSP2: 2
183 | Standalone: 5
184 | Tizen: 2
185 | WebGL: 3
186 | WiiU: 5
187 | Windows Store Apps: 5
188 | XboxOne: 5
189 | iPhone: 2
190 | tvOS: 2
191 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBXCapabilityType.cs:
--------------------------------------------------------------------------------
1 | namespace Strings.iOS.Xcode
2 | {
3 | ///
4 | /// List of all the capabilities available.
5 | ///
6 | public sealed class PBXCapabilityType
7 | {
8 | public static readonly PBXCapabilityType ApplePay = new PBXCapabilityType ("com.apple.ApplePay", true);
9 | public static readonly PBXCapabilityType AppGroups = new PBXCapabilityType ("com.apple.ApplicationGroups.iOS", true);
10 | public static readonly PBXCapabilityType AssociatedDomains = new PBXCapabilityType ("com.apple.SafariKeychain", true);
11 | public static readonly PBXCapabilityType BackgroundModes = new PBXCapabilityType ("com.apple.BackgroundModes", false);
12 | public static readonly PBXCapabilityType DataProtection = new PBXCapabilityType ("com.apple.DataProtection", true);
13 | public static readonly PBXCapabilityType GameCenter = new PBXCapabilityType ("com.apple.GameCenter", false, "GameKit.framework");
14 | public static readonly PBXCapabilityType HealthKit = new PBXCapabilityType ("com.apple.HealthKit", true, "HealthKit.framework");
15 | public static readonly PBXCapabilityType HomeKit = new PBXCapabilityType ("com.apple.HomeKit", true, "HomeKit.framework");
16 | public static readonly PBXCapabilityType iCloud = new PBXCapabilityType("com.apple.iCloud", true, "CloudKit.framework", true);
17 | public static readonly PBXCapabilityType InAppPurchase = new PBXCapabilityType ("com.apple.InAppPurchase", false);
18 | public static readonly PBXCapabilityType InterAppAudio = new PBXCapabilityType ("com.apple.InterAppAudio", true, "AudioToolbox.framework");
19 | public static readonly PBXCapabilityType KeychainSharing = new PBXCapabilityType ("com.apple.KeychainSharing", true);
20 | public static readonly PBXCapabilityType Maps = new PBXCapabilityType("com.apple.Maps.iOS", false, "MapKit.framework");
21 | public static readonly PBXCapabilityType PersonalVPN = new PBXCapabilityType("com.apple.VPNLite", true, "NetworkExtension.framework");
22 | public static readonly PBXCapabilityType PushNotifications = new PBXCapabilityType ("com.apple.Push", true);
23 | public static readonly PBXCapabilityType Siri = new PBXCapabilityType ("com.apple.Siri", true);
24 | public static readonly PBXCapabilityType Wallet = new PBXCapabilityType ("com.apple.Wallet", true, "PassKit.framework");
25 | public static readonly PBXCapabilityType WirelessAccessoryConfiguration = new PBXCapabilityType("com.apple.WAC", true, "ExternalAccessory.framework");
26 |
27 | private readonly string m_ID;
28 | private readonly bool m_RequiresEntitlements;
29 | private readonly string m_Framework;
30 | private readonly bool m_OptionalFramework;
31 |
32 | public bool optionalFramework
33 | {
34 | get { return m_OptionalFramework; }
35 | }
36 |
37 | public string framework
38 | {
39 | get { return m_Framework; }
40 | }
41 |
42 | public string id
43 | {
44 | get { return m_ID; }
45 | }
46 |
47 | public bool requiresEntitlements
48 | {
49 | get { return m_RequiresEntitlements; }
50 | }
51 |
52 | public struct TargetCapabilityPair
53 | {
54 | public string targetGuid;
55 | public PBXCapabilityType capability;
56 |
57 | public TargetCapabilityPair(string guid, PBXCapabilityType type)
58 | {
59 | targetGuid = guid;
60 | capability = type;
61 | }
62 | }
63 |
64 | ///
65 | /// This private object represents what a capability changes in the PBXProject file
66 | ///
67 | /// The string used in the PBXProject file to identify the capability and mark it as enabled.
68 | /// This capability requires an entitlements file therefore we need to add this entitlements file to the code signing entitlement.
69 | /// Specify which framework need to be added to the project for this capability, if "" no framework are added.
70 | /// Some capability (right now only iCloud) adds a framework, not all the time but just when some option are checked
71 | /// this parameter indicates if one of them is checked.
72 | private PBXCapabilityType(string _id, bool _requiresEntitlements, string _framework = "", bool _optionalFramework = false)
73 | {
74 | m_ID = _id;
75 | m_RequiresEntitlements = _requiresEntitlements;
76 | m_Framework = _framework;
77 | m_OptionalFramework = _optionalFramework;
78 | }
79 |
80 | public static PBXCapabilityType StringToPBXCapabilityType(string cap)
81 | {
82 | switch (cap)
83 | {
84 | case "com.apple.ApplePay":
85 | return ApplePay;
86 | case "com.apple.ApplicationGroups.iOS":
87 | return AppGroups;
88 | case "com.apple.SafariKeychain":
89 | return AssociatedDomains;
90 | case "com.apple.BackgroundModes":
91 | return BackgroundModes;
92 | case "com.apple.DataProtection":
93 | return DataProtection;
94 | case "com.apple.GameCenter":
95 | return GameCenter;
96 | case "com.apple.HealthKit":
97 | return HealthKit;
98 | case "com.apple.HomeKit":
99 | return HomeKit;
100 | case "com.apple.iCloud":
101 | return iCloud;
102 | case "com.apple.InAppPurchase":
103 | return InAppPurchase;
104 | case "com.apple.InterAppAudio":
105 | return InterAppAudio;
106 | case "com.apple.KeychainSharing":
107 | return KeychainSharing;
108 | case "com.apple.Maps.iOS":
109 | return Maps;
110 | case "com.apple.VPNLite":
111 | return PersonalVPN;
112 | case "com.apple.Push":
113 | return PushNotifications;
114 | case "com.apple.Siri":
115 | return Siri;
116 | case "com.apple.Wallet":
117 | return Wallet;
118 | case "WAC":
119 | return WirelessAccessoryConfiguration;
120 | default:
121 | return null;
122 | }
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/ProjectSettings/InputManager.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!13 &1
4 | InputManager:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | m_Axes:
8 | - serializedVersion: 3
9 | m_Name: Horizontal
10 | descriptiveName:
11 | descriptiveNegativeName:
12 | negativeButton: left
13 | positiveButton: right
14 | altNegativeButton: a
15 | altPositiveButton: d
16 | gravity: 3
17 | dead: 0.001
18 | sensitivity: 3
19 | snap: 1
20 | invert: 0
21 | type: 0
22 | axis: 0
23 | joyNum: 0
24 | - serializedVersion: 3
25 | m_Name: Vertical
26 | descriptiveName:
27 | descriptiveNegativeName:
28 | negativeButton: down
29 | positiveButton: up
30 | altNegativeButton: s
31 | altPositiveButton: w
32 | gravity: 3
33 | dead: 0.001
34 | sensitivity: 3
35 | snap: 1
36 | invert: 0
37 | type: 0
38 | axis: 0
39 | joyNum: 0
40 | - serializedVersion: 3
41 | m_Name: Fire1
42 | descriptiveName:
43 | descriptiveNegativeName:
44 | negativeButton:
45 | positiveButton: left ctrl
46 | altNegativeButton:
47 | altPositiveButton: mouse 0
48 | gravity: 1000
49 | dead: 0.001
50 | sensitivity: 1000
51 | snap: 0
52 | invert: 0
53 | type: 0
54 | axis: 0
55 | joyNum: 0
56 | - serializedVersion: 3
57 | m_Name: Fire2
58 | descriptiveName:
59 | descriptiveNegativeName:
60 | negativeButton:
61 | positiveButton: left alt
62 | altNegativeButton:
63 | altPositiveButton: mouse 1
64 | gravity: 1000
65 | dead: 0.001
66 | sensitivity: 1000
67 | snap: 0
68 | invert: 0
69 | type: 0
70 | axis: 0
71 | joyNum: 0
72 | - serializedVersion: 3
73 | m_Name: Fire3
74 | descriptiveName:
75 | descriptiveNegativeName:
76 | negativeButton:
77 | positiveButton: left shift
78 | altNegativeButton:
79 | altPositiveButton: mouse 2
80 | gravity: 1000
81 | dead: 0.001
82 | sensitivity: 1000
83 | snap: 0
84 | invert: 0
85 | type: 0
86 | axis: 0
87 | joyNum: 0
88 | - serializedVersion: 3
89 | m_Name: Jump
90 | descriptiveName:
91 | descriptiveNegativeName:
92 | negativeButton:
93 | positiveButton: space
94 | altNegativeButton:
95 | altPositiveButton:
96 | gravity: 1000
97 | dead: 0.001
98 | sensitivity: 1000
99 | snap: 0
100 | invert: 0
101 | type: 0
102 | axis: 0
103 | joyNum: 0
104 | - serializedVersion: 3
105 | m_Name: Mouse X
106 | descriptiveName:
107 | descriptiveNegativeName:
108 | negativeButton:
109 | positiveButton:
110 | altNegativeButton:
111 | altPositiveButton:
112 | gravity: 0
113 | dead: 0
114 | sensitivity: 0.1
115 | snap: 0
116 | invert: 0
117 | type: 1
118 | axis: 0
119 | joyNum: 0
120 | - serializedVersion: 3
121 | m_Name: Mouse Y
122 | descriptiveName:
123 | descriptiveNegativeName:
124 | negativeButton:
125 | positiveButton:
126 | altNegativeButton:
127 | altPositiveButton:
128 | gravity: 0
129 | dead: 0
130 | sensitivity: 0.1
131 | snap: 0
132 | invert: 0
133 | type: 1
134 | axis: 1
135 | joyNum: 0
136 | - serializedVersion: 3
137 | m_Name: Mouse ScrollWheel
138 | descriptiveName:
139 | descriptiveNegativeName:
140 | negativeButton:
141 | positiveButton:
142 | altNegativeButton:
143 | altPositiveButton:
144 | gravity: 0
145 | dead: 0
146 | sensitivity: 0.1
147 | snap: 0
148 | invert: 0
149 | type: 1
150 | axis: 2
151 | joyNum: 0
152 | - serializedVersion: 3
153 | m_Name: Horizontal
154 | descriptiveName:
155 | descriptiveNegativeName:
156 | negativeButton:
157 | positiveButton:
158 | altNegativeButton:
159 | altPositiveButton:
160 | gravity: 0
161 | dead: 0.19
162 | sensitivity: 1
163 | snap: 0
164 | invert: 0
165 | type: 2
166 | axis: 0
167 | joyNum: 0
168 | - serializedVersion: 3
169 | m_Name: Vertical
170 | descriptiveName:
171 | descriptiveNegativeName:
172 | negativeButton:
173 | positiveButton:
174 | altNegativeButton:
175 | altPositiveButton:
176 | gravity: 0
177 | dead: 0.19
178 | sensitivity: 1
179 | snap: 0
180 | invert: 1
181 | type: 2
182 | axis: 1
183 | joyNum: 0
184 | - serializedVersion: 3
185 | m_Name: Fire1
186 | descriptiveName:
187 | descriptiveNegativeName:
188 | negativeButton:
189 | positiveButton: joystick button 0
190 | altNegativeButton:
191 | altPositiveButton:
192 | gravity: 1000
193 | dead: 0.001
194 | sensitivity: 1000
195 | snap: 0
196 | invert: 0
197 | type: 0
198 | axis: 0
199 | joyNum: 0
200 | - serializedVersion: 3
201 | m_Name: Fire2
202 | descriptiveName:
203 | descriptiveNegativeName:
204 | negativeButton:
205 | positiveButton: joystick button 1
206 | altNegativeButton:
207 | altPositiveButton:
208 | gravity: 1000
209 | dead: 0.001
210 | sensitivity: 1000
211 | snap: 0
212 | invert: 0
213 | type: 0
214 | axis: 0
215 | joyNum: 0
216 | - serializedVersion: 3
217 | m_Name: Fire3
218 | descriptiveName:
219 | descriptiveNegativeName:
220 | negativeButton:
221 | positiveButton: joystick button 2
222 | altNegativeButton:
223 | altPositiveButton:
224 | gravity: 1000
225 | dead: 0.001
226 | sensitivity: 1000
227 | snap: 0
228 | invert: 0
229 | type: 0
230 | axis: 0
231 | joyNum: 0
232 | - serializedVersion: 3
233 | m_Name: Jump
234 | descriptiveName:
235 | descriptiveNegativeName:
236 | negativeButton:
237 | positiveButton: joystick button 3
238 | altNegativeButton:
239 | altPositiveButton:
240 | gravity: 1000
241 | dead: 0.001
242 | sensitivity: 1000
243 | snap: 0
244 | invert: 0
245 | type: 0
246 | axis: 0
247 | joyNum: 0
248 | - serializedVersion: 3
249 | m_Name: Submit
250 | descriptiveName:
251 | descriptiveNegativeName:
252 | negativeButton:
253 | positiveButton: return
254 | altNegativeButton:
255 | altPositiveButton: joystick button 0
256 | gravity: 1000
257 | dead: 0.001
258 | sensitivity: 1000
259 | snap: 0
260 | invert: 0
261 | type: 0
262 | axis: 0
263 | joyNum: 0
264 | - serializedVersion: 3
265 | m_Name: Submit
266 | descriptiveName:
267 | descriptiveNegativeName:
268 | negativeButton:
269 | positiveButton: enter
270 | altNegativeButton:
271 | altPositiveButton: space
272 | gravity: 1000
273 | dead: 0.001
274 | sensitivity: 1000
275 | snap: 0
276 | invert: 0
277 | type: 0
278 | axis: 0
279 | joyNum: 0
280 | - serializedVersion: 3
281 | m_Name: Cancel
282 | descriptiveName:
283 | descriptiveNegativeName:
284 | negativeButton:
285 | positiveButton: escape
286 | altNegativeButton:
287 | altPositiveButton: joystick button 1
288 | gravity: 1000
289 | dead: 0.001
290 | sensitivity: 1000
291 | snap: 0
292 | invert: 0
293 | type: 0
294 | axis: 0
295 | joyNum: 0
296 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBX/Lexer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Text.RegularExpressions;
3 | using System.IO;
4 | using System.Linq;
5 | using System;
6 |
7 |
8 | namespace Strings.iOS.Xcode.PBX
9 | {
10 | enum TokenType
11 | {
12 | EOF,
13 | Invalid,
14 | String,
15 | QuotedString,
16 | Comment,
17 |
18 | Semicolon, // ;
19 | Comma, // ,
20 | Eq, // =
21 | LParen, // (
22 | RParen, // )
23 | LBrace, // {
24 | RBrace, // }
25 | }
26 |
27 | class Token
28 | {
29 | public TokenType type;
30 |
31 | // the line of the input stream the token starts in (0-based)
32 | public int line;
33 |
34 | // start and past-the-end positions of the token in the input stream
35 | public int begin, end;
36 | }
37 |
38 | class TokenList : List
39 | {
40 | }
41 |
42 | class Lexer
43 | {
44 | string text;
45 | int pos;
46 | int length;
47 | int line;
48 |
49 | public static TokenList Tokenize(string text)
50 | {
51 | var lexer = new Lexer();
52 | lexer.SetText(text);
53 | return lexer.ScanAll();
54 | }
55 |
56 | public void SetText(string text)
57 | {
58 | this.text = text + " "; // to prevent out-of-bounds access during look ahead
59 | pos = 0;
60 | length = text.Length;
61 | line = 0;
62 | }
63 |
64 | public TokenList ScanAll()
65 | {
66 | var tokens = new TokenList();
67 |
68 | while (true)
69 | {
70 | var tok = new Token();
71 | ScanOne(tok);
72 | tokens.Add(tok);
73 | if (tok.type == TokenType.EOF)
74 | break;
75 | }
76 | return tokens;
77 | }
78 |
79 | void UpdateNewlineStats(char ch)
80 | {
81 | if (ch == '\n')
82 | line++;
83 | }
84 |
85 | // tokens list is modified in the case when we add BrokenLine token and need to remove already
86 | // added tokens for the current line
87 | void ScanOne(Token tok)
88 | {
89 | while (true)
90 | {
91 | while (pos < length && Char.IsWhiteSpace(text[pos]))
92 | {
93 | UpdateNewlineStats(text[pos]);
94 | pos++;
95 | }
96 |
97 | if (pos >= length)
98 | {
99 | tok.type = TokenType.EOF;
100 | break;
101 | }
102 |
103 | char ch = text[pos];
104 | char ch2 = text[pos+1];
105 |
106 | if (ch == '\"')
107 | ScanQuotedString(tok);
108 | else if (ch == '/' && ch2 == '*')
109 | ScanMultilineComment(tok);
110 | else if (ch == '/' && ch2 == '/')
111 | ScanComment(tok);
112 | else if (IsOperator(ch))
113 | ScanOperator(tok);
114 | else
115 | ScanString(tok); // be more robust and accept whatever is left
116 | return;
117 | }
118 | }
119 |
120 | void ScanString(Token tok)
121 | {
122 | tok.type = TokenType.String;
123 | tok.begin = pos;
124 | while (pos < length)
125 | {
126 | char ch = text[pos];
127 | char ch2 = text[pos+1];
128 |
129 | if (Char.IsWhiteSpace(ch))
130 | break;
131 | else if (ch == '\"')
132 | break;
133 | else if (ch == '/' && ch2 == '*')
134 | break;
135 | else if (ch == '/' && ch2 == '/')
136 | break;
137 | else if (IsOperator(ch))
138 | break;
139 | pos++;
140 | }
141 | tok.end = pos;
142 | tok.line = line;
143 | }
144 |
145 | void ScanQuotedString(Token tok)
146 | {
147 | tok.type = TokenType.QuotedString;
148 | tok.begin = pos;
149 | pos++;
150 |
151 | while (pos < length)
152 | {
153 | // ignore escaped quotes
154 | if (text[pos] == '\\' && text[pos+1] == '\"')
155 | {
156 | pos += 2;
157 | continue;
158 | }
159 |
160 | // note that we close unclosed quotes
161 | if (text[pos] == '\"')
162 | break;
163 |
164 | UpdateNewlineStats(text[pos]);
165 | pos++;
166 | }
167 | pos++;
168 | tok.end = pos;
169 | tok.line = line;
170 | }
171 |
172 | void ScanMultilineComment(Token tok)
173 | {
174 | tok.type = TokenType.Comment;
175 | tok.begin = pos;
176 | pos += 2;
177 |
178 | while (pos < length)
179 | {
180 | if (text[pos] == '*' && text[pos+1] == '/')
181 | break;
182 |
183 | // we support multiline comments
184 | UpdateNewlineStats(text[pos]);
185 | pos++;
186 | }
187 | pos += 2;
188 | tok.end = pos;
189 | tok.line = line;
190 | }
191 |
192 | void ScanComment(Token tok)
193 | {
194 | tok.type = TokenType.Comment;
195 | tok.begin = pos;
196 | pos += 2;
197 |
198 | while (pos < length)
199 | {
200 | if (text[pos] == '\n')
201 | break;
202 | pos++;
203 | }
204 | UpdateNewlineStats(text[pos]);
205 | pos++;
206 | tok.end = pos;
207 | tok.line = line;
208 | }
209 |
210 | bool IsOperator(char ch)
211 | {
212 | if (ch == ';' || ch == ',' || ch == '=' || ch == '(' || ch == ')' || ch == '{' || ch == '}')
213 | return true;
214 | return false;
215 | }
216 |
217 | void ScanOperator(Token tok)
218 | {
219 | switch (text[pos])
220 | {
221 | case ';': ScanOperatorSpecific(tok, TokenType.Semicolon); return;
222 | case ',': ScanOperatorSpecific(tok, TokenType.Comma); return;
223 | case '=': ScanOperatorSpecific(tok, TokenType.Eq); return;
224 | case '(': ScanOperatorSpecific(tok, TokenType.LParen); return;
225 | case ')': ScanOperatorSpecific(tok, TokenType.RParen); return;
226 | case '{': ScanOperatorSpecific(tok, TokenType.LBrace); return;
227 | case '}': ScanOperatorSpecific(tok, TokenType.RBrace); return;
228 | default: return;
229 | }
230 | }
231 |
232 | void ScanOperatorSpecific(Token tok, TokenType type)
233 | {
234 | tok.type = type;
235 | tok.begin = pos;
236 | pos++;
237 | tok.end = pos;
238 | tok.line = line;
239 | }
240 | }
241 |
242 |
243 | } // namespace UnityEditor.iOS.Xcode
--------------------------------------------------------------------------------
/Assets/Scenes/SampleScene.unity:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!29 &1
4 | OcclusionCullingSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 2
7 | m_OcclusionBakeSettings:
8 | smallestOccluder: 5
9 | smallestHole: 0.25
10 | backfaceThreshold: 100
11 | m_SceneGUID: 00000000000000000000000000000000
12 | m_OcclusionCullingData: {fileID: 0}
13 | --- !u!104 &2
14 | RenderSettings:
15 | m_ObjectHideFlags: 0
16 | serializedVersion: 9
17 | m_Fog: 0
18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
19 | m_FogMode: 3
20 | m_FogDensity: 0.01
21 | m_LinearFogStart: 0
22 | m_LinearFogEnd: 300
23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
26 | m_AmbientIntensity: 1
27 | m_AmbientMode: 0
28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
30 | m_HaloStrength: 0.5
31 | m_FlareStrength: 1
32 | m_FlareFadeSpeed: 3
33 | m_HaloTexture: {fileID: 0}
34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
35 | m_DefaultReflectionMode: 0
36 | m_DefaultReflectionResolution: 128
37 | m_ReflectionBounces: 1
38 | m_ReflectionIntensity: 1
39 | m_CustomReflection: {fileID: 0}
40 | m_Sun: {fileID: 170076734}
41 | m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
42 | m_UseRadianceAmbientProbe: 0
43 | --- !u!157 &3
44 | LightmapSettings:
45 | m_ObjectHideFlags: 0
46 | serializedVersion: 11
47 | m_GIWorkflowMode: 0
48 | m_GISettings:
49 | serializedVersion: 2
50 | m_BounceScale: 1
51 | m_IndirectOutputScale: 1
52 | m_AlbedoBoost: 1
53 | m_TemporalCoherenceThreshold: 1
54 | m_EnvironmentLightingMode: 0
55 | m_EnableBakedLightmaps: 1
56 | m_EnableRealtimeLightmaps: 0
57 | m_LightmapEditorSettings:
58 | serializedVersion: 10
59 | m_Resolution: 2
60 | m_BakeResolution: 10
61 | m_AtlasSize: 512
62 | m_AO: 0
63 | m_AOMaxDistance: 1
64 | m_CompAOExponent: 1
65 | m_CompAOExponentDirect: 0
66 | m_Padding: 2
67 | m_LightmapParameters: {fileID: 0}
68 | m_LightmapsBakeMode: 1
69 | m_TextureCompression: 1
70 | m_FinalGather: 0
71 | m_FinalGatherFiltering: 1
72 | m_FinalGatherRayCount: 256
73 | m_ReflectionCompression: 2
74 | m_MixedBakeMode: 2
75 | m_BakeBackend: 1
76 | m_PVRSampling: 1
77 | m_PVRDirectSampleCount: 32
78 | m_PVRSampleCount: 256
79 | m_PVRBounces: 2
80 | m_PVRFilterTypeDirect: 0
81 | m_PVRFilterTypeIndirect: 0
82 | m_PVRFilterTypeAO: 0
83 | m_PVRFilteringMode: 1
84 | m_PVRCulling: 1
85 | m_PVRFilteringGaussRadiusDirect: 1
86 | m_PVRFilteringGaussRadiusIndirect: 5
87 | m_PVRFilteringGaussRadiusAO: 2
88 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5
89 | m_PVRFilteringAtrousPositionSigmaIndirect: 2
90 | m_PVRFilteringAtrousPositionSigmaAO: 1
91 | m_ShowResolutionOverlay: 1
92 | m_LightingDataAsset: {fileID: 0}
93 | m_UseShadowmask: 1
94 | --- !u!196 &4
95 | NavMeshSettings:
96 | serializedVersion: 2
97 | m_ObjectHideFlags: 0
98 | m_BuildSettings:
99 | serializedVersion: 2
100 | agentTypeID: 0
101 | agentRadius: 0.5
102 | agentHeight: 2
103 | agentSlope: 45
104 | agentClimb: 0.4
105 | ledgeDropHeight: 0
106 | maxJumpAcrossDistance: 0
107 | minRegionArea: 2
108 | manualCellSize: 0
109 | cellSize: 0.16666667
110 | manualTileSize: 0
111 | tileSize: 256
112 | accuratePlacement: 0
113 | debug:
114 | m_Flags: 0
115 | m_NavMeshData: {fileID: 0}
116 | --- !u!1 &170076733
117 | GameObject:
118 | m_ObjectHideFlags: 0
119 | m_CorrespondingSourceObject: {fileID: 0}
120 | m_PrefabInternal: {fileID: 0}
121 | serializedVersion: 6
122 | m_Component:
123 | - component: {fileID: 170076735}
124 | - component: {fileID: 170076734}
125 | m_Layer: 0
126 | m_Name: Directional Light
127 | m_TagString: Untagged
128 | m_Icon: {fileID: 0}
129 | m_NavMeshLayer: 0
130 | m_StaticEditorFlags: 0
131 | m_IsActive: 1
132 | --- !u!108 &170076734
133 | Light:
134 | m_ObjectHideFlags: 0
135 | m_CorrespondingSourceObject: {fileID: 0}
136 | m_PrefabInternal: {fileID: 0}
137 | m_GameObject: {fileID: 170076733}
138 | m_Enabled: 1
139 | serializedVersion: 8
140 | m_Type: 1
141 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
142 | m_Intensity: 1
143 | m_Range: 10
144 | m_SpotAngle: 30
145 | m_CookieSize: 10
146 | m_Shadows:
147 | m_Type: 2
148 | m_Resolution: -1
149 | m_CustomResolution: -1
150 | m_Strength: 1
151 | m_Bias: 0.05
152 | m_NormalBias: 0.4
153 | m_NearPlane: 0.2
154 | m_Cookie: {fileID: 0}
155 | m_DrawHalo: 0
156 | m_Flare: {fileID: 0}
157 | m_RenderMode: 0
158 | m_CullingMask:
159 | serializedVersion: 2
160 | m_Bits: 4294967295
161 | m_Lightmapping: 1
162 | m_LightShadowCasterMode: 0
163 | m_AreaSize: {x: 1, y: 1}
164 | m_BounceIntensity: 1
165 | m_ColorTemperature: 6570
166 | m_UseColorTemperature: 0
167 | m_ShadowRadius: 0
168 | m_ShadowAngle: 0
169 | --- !u!4 &170076735
170 | Transform:
171 | m_ObjectHideFlags: 0
172 | m_CorrespondingSourceObject: {fileID: 0}
173 | m_PrefabInternal: {fileID: 0}
174 | m_GameObject: {fileID: 170076733}
175 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
176 | m_LocalPosition: {x: 0, y: 3, z: 0}
177 | m_LocalScale: {x: 1, y: 1, z: 1}
178 | m_Children: []
179 | m_Father: {fileID: 0}
180 | m_RootOrder: 1
181 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
182 | --- !u!1 &534669902
183 | GameObject:
184 | m_ObjectHideFlags: 0
185 | m_CorrespondingSourceObject: {fileID: 0}
186 | m_PrefabInternal: {fileID: 0}
187 | serializedVersion: 6
188 | m_Component:
189 | - component: {fileID: 534669905}
190 | - component: {fileID: 534669904}
191 | - component: {fileID: 534669903}
192 | m_Layer: 0
193 | m_Name: Main Camera
194 | m_TagString: MainCamera
195 | m_Icon: {fileID: 0}
196 | m_NavMeshLayer: 0
197 | m_StaticEditorFlags: 0
198 | m_IsActive: 1
199 | --- !u!81 &534669903
200 | AudioListener:
201 | m_ObjectHideFlags: 0
202 | m_CorrespondingSourceObject: {fileID: 0}
203 | m_PrefabInternal: {fileID: 0}
204 | m_GameObject: {fileID: 534669902}
205 | m_Enabled: 1
206 | --- !u!20 &534669904
207 | Camera:
208 | m_ObjectHideFlags: 0
209 | m_CorrespondingSourceObject: {fileID: 0}
210 | m_PrefabInternal: {fileID: 0}
211 | m_GameObject: {fileID: 534669902}
212 | m_Enabled: 1
213 | serializedVersion: 2
214 | m_ClearFlags: 1
215 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0}
216 | m_projectionMatrixMode: 1
217 | m_SensorSize: {x: 36, y: 24}
218 | m_LensShift: {x: 0, y: 0}
219 | m_GateFitMode: 2
220 | m_FocalLength: 50
221 | m_NormalizedViewPortRect:
222 | serializedVersion: 2
223 | x: 0
224 | y: 0
225 | width: 1
226 | height: 1
227 | near clip plane: 0.3
228 | far clip plane: 1000
229 | field of view: 60
230 | orthographic: 0
231 | orthographic size: 5
232 | m_Depth: -1
233 | m_CullingMask:
234 | serializedVersion: 2
235 | m_Bits: 4294967295
236 | m_RenderingPath: -1
237 | m_TargetTexture: {fileID: 0}
238 | m_TargetDisplay: 0
239 | m_TargetEye: 3
240 | m_HDR: 1
241 | m_AllowMSAA: 1
242 | m_AllowDynamicResolution: 0
243 | m_ForceIntoRT: 0
244 | m_OcclusionCulling: 1
245 | m_StereoConvergence: 10
246 | m_StereoSeparation: 0.022
247 | --- !u!4 &534669905
248 | Transform:
249 | m_ObjectHideFlags: 0
250 | m_CorrespondingSourceObject: {fileID: 0}
251 | m_PrefabInternal: {fileID: 0}
252 | m_GameObject: {fileID: 534669902}
253 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
254 | m_LocalPosition: {x: 0, y: 1, z: -10}
255 | m_LocalScale: {x: 1, y: 1, z: 1}
256 | m_Children: []
257 | m_Father: {fileID: 0}
258 | m_RootOrder: 0
259 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
260 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/JsonParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Text;
5 | using System.Linq;
6 |
7 | namespace Strings.iOS.Xcode
8 | {
9 | internal class JsonElement
10 | {
11 | protected JsonElement() {}
12 |
13 | // convenience methods
14 | public string AsString() { return ((JsonElementString)this).value; }
15 | public int AsInteger() { return ((JsonElementInteger)this).value; }
16 | public bool AsBoolean() { return ((JsonElementBoolean)this).value; }
17 | public JsonElementArray AsArray() { return (JsonElementArray)this; }
18 | public JsonElementDict AsDict() { return (JsonElementDict)this; }
19 |
20 | public JsonElement this[string key]
21 | {
22 | get { return AsDict()[key]; }
23 | set { AsDict()[key] = value; }
24 | }
25 | }
26 |
27 | internal class JsonElementString : JsonElement
28 | {
29 | public JsonElementString(string v) { value = v; }
30 |
31 | public string value;
32 | }
33 |
34 | internal class JsonElementInteger : JsonElement
35 | {
36 | public JsonElementInteger(int v) { value = v; }
37 |
38 | public int value;
39 | }
40 |
41 | internal class JsonElementBoolean : JsonElement
42 | {
43 | public JsonElementBoolean(bool v) { value = v; }
44 |
45 | public bool value;
46 | }
47 |
48 | internal class JsonElementDict : JsonElement
49 | {
50 | public JsonElementDict() : base() {}
51 |
52 | private SortedDictionary m_PrivateValue = new SortedDictionary();
53 | public IDictionary values { get { return m_PrivateValue; }}
54 |
55 | new public JsonElement this[string key]
56 | {
57 | get {
58 | if (values.ContainsKey(key))
59 | return values[key];
60 | return null;
61 | }
62 | set { this.values[key] = value; }
63 | }
64 |
65 | public bool Contains(string key)
66 | {
67 | return values.ContainsKey(key);
68 | }
69 |
70 | public void Remove(string key)
71 | {
72 | values.Remove(key);
73 | }
74 |
75 | // convenience methods
76 | public void SetInteger(string key, int val)
77 | {
78 | values[key] = new JsonElementInteger(val);
79 | }
80 |
81 | public void SetString(string key, string val)
82 | {
83 | values[key] = new JsonElementString(val);
84 | }
85 |
86 | public void SetBoolean(string key, bool val)
87 | {
88 | values[key] = new JsonElementBoolean(val);
89 | }
90 |
91 | public JsonElementArray CreateArray(string key)
92 | {
93 | var v = new JsonElementArray();
94 | values[key] = v;
95 | return v;
96 | }
97 |
98 | public JsonElementDict CreateDict(string key)
99 | {
100 | var v = new JsonElementDict();
101 | values[key] = v;
102 | return v;
103 | }
104 | }
105 |
106 | internal class JsonElementArray : JsonElement
107 | {
108 | public JsonElementArray() : base() {}
109 | public List values = new List();
110 |
111 | // convenience methods
112 | public void AddString(string val)
113 | {
114 | values.Add(new JsonElementString(val));
115 | }
116 |
117 | public void AddInteger(int val)
118 | {
119 | values.Add(new JsonElementInteger(val));
120 | }
121 |
122 | public void AddBoolean(bool val)
123 | {
124 | values.Add(new JsonElementBoolean(val));
125 | }
126 |
127 | public JsonElementArray AddArray()
128 | {
129 | var v = new JsonElementArray();
130 | values.Add(v);
131 | return v;
132 | }
133 |
134 | public JsonElementDict AddDict()
135 | {
136 | var v = new JsonElementDict();
137 | values.Add(v);
138 | return v;
139 | }
140 | }
141 |
142 | internal class JsonDocument
143 | {
144 | public JsonElementDict root;
145 | public string indentString = " ";
146 |
147 | public JsonDocument()
148 | {
149 | root = new JsonElementDict();
150 | }
151 |
152 | void AppendIndent(StringBuilder sb, int indent)
153 | {
154 | for (int i = 0; i < indent; ++i)
155 | sb.Append(indentString);
156 | }
157 |
158 | void WriteString(StringBuilder sb, string str)
159 | {
160 | // TODO: escape
161 | sb.Append('"');
162 | sb.Append(str);
163 | sb.Append('"');
164 | }
165 |
166 | void WriteBoolean(StringBuilder sb, bool value)
167 | {
168 | sb.Append(value ? "true" : "false");
169 | }
170 |
171 | void WriteInteger(StringBuilder sb, int value)
172 | {
173 | sb.Append(value.ToString());
174 | }
175 |
176 | void WriteDictKeyValue(StringBuilder sb, string key, JsonElement value, int indent)
177 | {
178 | sb.Append("\n");
179 | AppendIndent(sb, indent);
180 | WriteString(sb, key);
181 | sb.Append(" : ");
182 | if (value is JsonElementString)
183 | WriteString(sb, value.AsString());
184 | else if (value is JsonElementInteger)
185 | WriteInteger(sb, value.AsInteger());
186 | else if (value is JsonElementBoolean)
187 | WriteBoolean(sb, value.AsBoolean());
188 | else if (value is JsonElementDict)
189 | WriteDict(sb, value.AsDict(), indent);
190 | else if (value is JsonElementArray)
191 | WriteArray(sb, value.AsArray(), indent);
192 | }
193 |
194 | void WriteDict(StringBuilder sb, JsonElementDict el, int indent)
195 | {
196 | sb.Append("{");
197 | bool hasElement = false;
198 | foreach (var key in el.values.Keys)
199 | {
200 | if (hasElement)
201 | sb.Append(","); // trailing commas not supported
202 | WriteDictKeyValue(sb, key, el[key], indent+1);
203 | hasElement = true;
204 | }
205 | sb.Append("\n");
206 | AppendIndent(sb, indent);
207 | sb.Append("}");
208 | }
209 |
210 | void WriteArray(StringBuilder sb, JsonElementArray el, int indent)
211 | {
212 | sb.Append("[");
213 | bool hasElement = false;
214 | foreach (var value in el.values)
215 | {
216 | if (hasElement)
217 | sb.Append(","); // trailing commas not supported
218 | sb.Append("\n");
219 | AppendIndent(sb, indent+1);
220 |
221 | if (value is JsonElementString)
222 | WriteString(sb, value.AsString());
223 | else if (value is JsonElementInteger)
224 | WriteInteger(sb, value.AsInteger());
225 | else if (value is JsonElementBoolean)
226 | WriteBoolean(sb, value.AsBoolean());
227 | else if (value is JsonElementDict)
228 | WriteDict(sb, value.AsDict(), indent+1);
229 | else if (value is JsonElementArray)
230 | WriteArray(sb, value.AsArray(), indent+1);
231 | hasElement = true;
232 | }
233 | sb.Append("\n");
234 | AppendIndent(sb, indent);
235 | sb.Append("]");
236 | }
237 |
238 | public void WriteToFile(string path)
239 | {
240 | File.WriteAllText(path, WriteToString());
241 | }
242 |
243 | public void WriteToStream(TextWriter tw)
244 | {
245 | tw.Write(WriteToString());
246 | }
247 |
248 | public string WriteToString()
249 | {
250 | var sb = new StringBuilder();
251 | WriteDict(sb, root, 0);
252 | return sb.ToString();
253 | }
254 | }
255 |
256 |
257 | } // namespace UnityEditor.iOS.Xcode
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBX/Serializer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Text.RegularExpressions;
5 | using System.IO;
6 | using System.Linq;
7 |
8 | namespace Strings.iOS.Xcode.PBX
9 | {
10 | class PropertyCommentChecker
11 | {
12 | private int m_Level;
13 | private bool m_All;
14 | private List> m_Props;
15 |
16 | /* The argument is an array of matcher strings each of which determine
17 | whether a property with a certain path needs to be decorated with a
18 | comment.
19 |
20 | A path is a number of path elements concatenated by '/'. The last path
21 | element is either:
22 | the key if we're referring to a dict key
23 | the value if we're referring to a value in an array
24 | the value if we're referring to a value in a dict
25 | All other path elements are either:
26 | the key if the container is dict
27 | '*' if the container is array
28 |
29 | Path matcher has the same structure as a path, except that any of the
30 | elements may be '*'. Matcher matches a path if both have the same number
31 | of elements and for each pair matcher element is the same as path element
32 | or is '*'.
33 |
34 | a/b/c matches a/b/c but not a/b nor a/b/c/d
35 | a/* /c matches a/d/c but not a/b nor a/b/c/d
36 | * /* /* matches any path from three elements
37 | */
38 | protected PropertyCommentChecker(int level, List> props)
39 | {
40 | m_Level = level;
41 | m_All = false;
42 | m_Props = props;
43 | }
44 |
45 | public PropertyCommentChecker()
46 | {
47 | m_Level = 0;
48 | m_All = false;
49 | m_Props = new List>();
50 | }
51 |
52 | public PropertyCommentChecker(IEnumerable props)
53 | {
54 | m_Level = 0;
55 | m_All = false;
56 | m_Props = new List>();
57 | foreach (var prop in props)
58 | {
59 | m_Props.Add(new List(prop.Split('/')));
60 | }
61 | }
62 |
63 | bool CheckContained(string prop)
64 | {
65 | if (m_All)
66 | return true;
67 | foreach (var list in m_Props)
68 | {
69 | if (list.Count == m_Level+1)
70 | {
71 | if (list[m_Level] == prop)
72 | return true;
73 | if (list[m_Level] == "*")
74 | {
75 | m_All = true; // short-circuit all at this level
76 | return true;
77 | }
78 | }
79 | }
80 | return false;
81 | }
82 |
83 | public bool CheckStringValueInArray(string value) { return CheckContained(value); }
84 | public bool CheckKeyInDict(string key) { return CheckContained(key); }
85 |
86 | public bool CheckStringValueInDict(string key, string value)
87 | {
88 | foreach (var list in m_Props)
89 | {
90 | if (list.Count == m_Level + 2)
91 | {
92 | if ((list[m_Level] == "*" || list[m_Level] == key) &&
93 | list[m_Level+1] == "*" || list[m_Level+1] == value)
94 | return true;
95 | }
96 | }
97 | return false;
98 | }
99 |
100 | public PropertyCommentChecker NextLevel(string prop)
101 | {
102 | var newList = new List>();
103 | foreach (var list in m_Props)
104 | {
105 | if (list.Count <= m_Level+1)
106 | continue;
107 | if (list[m_Level] == "*" || list[m_Level] == prop)
108 | newList.Add(list);
109 | }
110 | return new PropertyCommentChecker(m_Level + 1, newList);
111 | }
112 | }
113 |
114 | class Serializer
115 | {
116 | public static PBXElementDict ParseTreeAST(TreeAST ast, TokenList tokens, string text)
117 | {
118 | var el = new PBXElementDict();
119 | foreach (var kv in ast.values)
120 | {
121 | PBXElementString key = ParseIdentifierAST(kv.key, tokens, text);
122 | PBXElement value = ParseValueAST(kv.value, tokens, text);
123 | el[key.value] = value;
124 | }
125 | return el;
126 | }
127 |
128 | public static PBXElementArray ParseArrayAST(ArrayAST ast, TokenList tokens, string text)
129 | {
130 | var el = new PBXElementArray();
131 | foreach (var v in ast.values)
132 | {
133 | el.values.Add(ParseValueAST(v, tokens, text));
134 | }
135 | return el;
136 | }
137 |
138 | public static PBXElement ParseValueAST(ValueAST ast, TokenList tokens, string text)
139 | {
140 | if (ast is TreeAST)
141 | return ParseTreeAST((TreeAST)ast, tokens, text);
142 | if (ast is ArrayAST)
143 | return ParseArrayAST((ArrayAST)ast, tokens, text);
144 | if (ast is IdentifierAST)
145 | return ParseIdentifierAST((IdentifierAST)ast, tokens, text);
146 | return null;
147 | }
148 |
149 | public static PBXElementString ParseIdentifierAST(IdentifierAST ast, TokenList tokens, string text)
150 | {
151 | Token tok = tokens[ast.value];
152 | string value;
153 | switch (tok.type)
154 | {
155 | case TokenType.String:
156 | value = text.Substring(tok.begin, tok.end - tok.begin);
157 | return new PBXElementString(value);
158 | case TokenType.QuotedString:
159 | value = text.Substring(tok.begin, tok.end - tok.begin);
160 | value = PBXStream.UnquoteString(value);
161 | return new PBXElementString(value);
162 | default:
163 | throw new Exception("Internal parser error");
164 | }
165 | }
166 |
167 | static string k_Indent = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
168 |
169 | static string GetIndent(int indent)
170 | {
171 | return k_Indent.Substring(0, indent);
172 | }
173 |
174 | static void WriteStringImpl(StringBuilder sb, string s, bool comment, GUIDToCommentMap comments)
175 | {
176 | if (comment)
177 | comments.WriteStringBuilder(sb, s);
178 | else
179 | sb.Append(PBXStream.QuoteStringIfNeeded(s));
180 | }
181 |
182 | public static void WriteDictKeyValue(StringBuilder sb, string key, PBXElement value, int indent, bool compact,
183 | PropertyCommentChecker checker, GUIDToCommentMap comments)
184 | {
185 | if (!compact)
186 | {
187 | sb.Append("\n");
188 | sb.Append(GetIndent(indent));
189 | }
190 | WriteStringImpl(sb, key, checker.CheckKeyInDict(key), comments);
191 | sb.Append(" = ");
192 |
193 | if (value is PBXElementString)
194 | WriteStringImpl(sb, value.AsString(), checker.CheckStringValueInDict(key, value.AsString()), comments);
195 | else if (value is PBXElementDict)
196 | WriteDict(sb, value.AsDict(), indent, compact, checker.NextLevel(key), comments);
197 | else if (value is PBXElementArray)
198 | WriteArray(sb, value.AsArray(), indent, compact, checker.NextLevel(key), comments);
199 | sb.Append(";");
200 | if (compact)
201 | sb.Append(" ");
202 | }
203 |
204 | public static void WriteDict(StringBuilder sb, PBXElementDict el, int indent, bool compact,
205 | PropertyCommentChecker checker, GUIDToCommentMap comments)
206 | {
207 | sb.Append("{");
208 |
209 | if (el.Contains("isa"))
210 | WriteDictKeyValue(sb, "isa", el["isa"], indent+1, compact, checker, comments);
211 | var keys = new List(el.values.Keys);
212 | keys.Sort(StringComparer.Ordinal);
213 | foreach (var key in keys)
214 | {
215 | if (key != "isa")
216 | WriteDictKeyValue(sb, key, el[key], indent+1, compact, checker, comments);
217 | }
218 | if (!compact)
219 | {
220 | sb.Append("\n");
221 | sb.Append(GetIndent(indent));
222 | }
223 | sb.Append("}");
224 | }
225 |
226 | public static void WriteArray(StringBuilder sb, PBXElementArray el, int indent, bool compact,
227 | PropertyCommentChecker checker, GUIDToCommentMap comments)
228 | {
229 | sb.Append("(");
230 | foreach (var value in el.values)
231 | {
232 | if (!compact)
233 | {
234 | sb.Append("\n");
235 | sb.Append(GetIndent(indent+1));
236 | }
237 |
238 | if (value is PBXElementString)
239 | WriteStringImpl(sb, value.AsString(), checker.CheckStringValueInArray(value.AsString()), comments);
240 | else if (value is PBXElementDict)
241 | WriteDict(sb, value.AsDict(), indent+1, compact, checker.NextLevel("*"), comments);
242 | else if (value is PBXElementArray)
243 | WriteArray(sb, value.AsArray(), indent+1, compact, checker.NextLevel("*"), comments);
244 | sb.Append(",");
245 | if (compact)
246 | sb.Append(" ");
247 | }
248 |
249 | if (!compact)
250 | {
251 | sb.Append("\n");
252 | sb.Append(GetIndent(indent));
253 | }
254 | sb.Append(")");
255 | }
256 | }
257 |
258 | } // namespace UnityEditor.iOS.Xcode
259 |
260 |
--------------------------------------------------------------------------------
/Packages/packages-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "com.unity.2d.sprite": {
4 | "version": "1.0.0",
5 | "depth": 0,
6 | "source": "builtin",
7 | "dependencies": {}
8 | },
9 | "com.unity.2d.tilemap": {
10 | "version": "1.0.0",
11 | "depth": 0,
12 | "source": "builtin",
13 | "dependencies": {}
14 | },
15 | "com.unity.ads": {
16 | "version": "3.7.1",
17 | "depth": 0,
18 | "source": "registry",
19 | "dependencies": {
20 | "com.unity.ugui": "1.0.0"
21 | },
22 | "url": "https://packages.unity.com"
23 | },
24 | "com.unity.analytics": {
25 | "version": "3.5.3",
26 | "depth": 0,
27 | "source": "registry",
28 | "dependencies": {
29 | "com.unity.ugui": "1.0.0"
30 | },
31 | "url": "https://packages.unity.com"
32 | },
33 | "com.unity.collab-proxy": {
34 | "version": "1.7.1",
35 | "depth": 0,
36 | "source": "registry",
37 | "dependencies": {
38 | "com.unity.nuget.newtonsoft-json": "2.0.0"
39 | },
40 | "url": "https://packages.unity.com"
41 | },
42 | "com.unity.ext.nunit": {
43 | "version": "1.0.6",
44 | "depth": 1,
45 | "source": "registry",
46 | "dependencies": {},
47 | "url": "https://packages.unity.com"
48 | },
49 | "com.unity.ide.rider": {
50 | "version": "2.0.7",
51 | "depth": 0,
52 | "source": "registry",
53 | "dependencies": {
54 | "com.unity.test-framework": "1.1.1"
55 | },
56 | "url": "https://packages.unity.com"
57 | },
58 | "com.unity.ide.visualstudio": {
59 | "version": "2.0.9",
60 | "depth": 0,
61 | "source": "registry",
62 | "dependencies": {
63 | "com.unity.test-framework": "1.1.9"
64 | },
65 | "url": "https://packages.unity.com"
66 | },
67 | "com.unity.ide.vscode": {
68 | "version": "1.2.3",
69 | "depth": 0,
70 | "source": "registry",
71 | "dependencies": {},
72 | "url": "https://packages.unity.com"
73 | },
74 | "com.unity.nuget.newtonsoft-json": {
75 | "version": "2.0.0",
76 | "depth": 1,
77 | "source": "registry",
78 | "dependencies": {},
79 | "url": "https://packages.unity.com"
80 | },
81 | "com.unity.purchasing": {
82 | "version": "3.2.2",
83 | "depth": 0,
84 | "source": "registry",
85 | "dependencies": {
86 | "com.unity.ugui": "1.0.0",
87 | "com.unity.modules.unityanalytics": "1.0.0",
88 | "com.unity.modules.unitywebrequest": "1.0.0",
89 | "com.unity.modules.jsonserialize": "1.0.0",
90 | "com.unity.modules.androidjni": "1.0.0"
91 | },
92 | "url": "https://packages.unity.com"
93 | },
94 | "com.unity.test-framework": {
95 | "version": "1.1.27",
96 | "depth": 0,
97 | "source": "registry",
98 | "dependencies": {
99 | "com.unity.ext.nunit": "1.0.6",
100 | "com.unity.modules.imgui": "1.0.0",
101 | "com.unity.modules.jsonserialize": "1.0.0"
102 | },
103 | "url": "https://packages.unity.com"
104 | },
105 | "com.unity.textmeshpro": {
106 | "version": "3.0.6",
107 | "depth": 0,
108 | "source": "registry",
109 | "dependencies": {
110 | "com.unity.ugui": "1.0.0"
111 | },
112 | "url": "https://packages.unity.com"
113 | },
114 | "com.unity.timeline": {
115 | "version": "1.4.8",
116 | "depth": 0,
117 | "source": "registry",
118 | "dependencies": {
119 | "com.unity.modules.director": "1.0.0",
120 | "com.unity.modules.animation": "1.0.0",
121 | "com.unity.modules.audio": "1.0.0",
122 | "com.unity.modules.particlesystem": "1.0.0"
123 | },
124 | "url": "https://packages.unity.com"
125 | },
126 | "com.unity.ugui": {
127 | "version": "1.0.0",
128 | "depth": 0,
129 | "source": "builtin",
130 | "dependencies": {
131 | "com.unity.modules.ui": "1.0.0",
132 | "com.unity.modules.imgui": "1.0.0"
133 | }
134 | },
135 | "com.unity.xr.legacyinputhelpers": {
136 | "version": "2.1.7",
137 | "depth": 0,
138 | "source": "registry",
139 | "dependencies": {
140 | "com.unity.modules.vr": "1.0.0",
141 | "com.unity.modules.xr": "1.0.0"
142 | },
143 | "url": "https://packages.unity.com"
144 | },
145 | "com.unity.modules.ai": {
146 | "version": "1.0.0",
147 | "depth": 0,
148 | "source": "builtin",
149 | "dependencies": {}
150 | },
151 | "com.unity.modules.androidjni": {
152 | "version": "1.0.0",
153 | "depth": 0,
154 | "source": "builtin",
155 | "dependencies": {}
156 | },
157 | "com.unity.modules.animation": {
158 | "version": "1.0.0",
159 | "depth": 0,
160 | "source": "builtin",
161 | "dependencies": {}
162 | },
163 | "com.unity.modules.assetbundle": {
164 | "version": "1.0.0",
165 | "depth": 0,
166 | "source": "builtin",
167 | "dependencies": {}
168 | },
169 | "com.unity.modules.audio": {
170 | "version": "1.0.0",
171 | "depth": 0,
172 | "source": "builtin",
173 | "dependencies": {}
174 | },
175 | "com.unity.modules.cloth": {
176 | "version": "1.0.0",
177 | "depth": 0,
178 | "source": "builtin",
179 | "dependencies": {
180 | "com.unity.modules.physics": "1.0.0"
181 | }
182 | },
183 | "com.unity.modules.director": {
184 | "version": "1.0.0",
185 | "depth": 0,
186 | "source": "builtin",
187 | "dependencies": {
188 | "com.unity.modules.audio": "1.0.0",
189 | "com.unity.modules.animation": "1.0.0"
190 | }
191 | },
192 | "com.unity.modules.imageconversion": {
193 | "version": "1.0.0",
194 | "depth": 0,
195 | "source": "builtin",
196 | "dependencies": {}
197 | },
198 | "com.unity.modules.imgui": {
199 | "version": "1.0.0",
200 | "depth": 0,
201 | "source": "builtin",
202 | "dependencies": {}
203 | },
204 | "com.unity.modules.jsonserialize": {
205 | "version": "1.0.0",
206 | "depth": 0,
207 | "source": "builtin",
208 | "dependencies": {}
209 | },
210 | "com.unity.modules.particlesystem": {
211 | "version": "1.0.0",
212 | "depth": 0,
213 | "source": "builtin",
214 | "dependencies": {}
215 | },
216 | "com.unity.modules.physics": {
217 | "version": "1.0.0",
218 | "depth": 0,
219 | "source": "builtin",
220 | "dependencies": {}
221 | },
222 | "com.unity.modules.physics2d": {
223 | "version": "1.0.0",
224 | "depth": 0,
225 | "source": "builtin",
226 | "dependencies": {}
227 | },
228 | "com.unity.modules.screencapture": {
229 | "version": "1.0.0",
230 | "depth": 0,
231 | "source": "builtin",
232 | "dependencies": {
233 | "com.unity.modules.imageconversion": "1.0.0"
234 | }
235 | },
236 | "com.unity.modules.subsystems": {
237 | "version": "1.0.0",
238 | "depth": 1,
239 | "source": "builtin",
240 | "dependencies": {
241 | "com.unity.modules.jsonserialize": "1.0.0"
242 | }
243 | },
244 | "com.unity.modules.terrain": {
245 | "version": "1.0.0",
246 | "depth": 0,
247 | "source": "builtin",
248 | "dependencies": {}
249 | },
250 | "com.unity.modules.terrainphysics": {
251 | "version": "1.0.0",
252 | "depth": 0,
253 | "source": "builtin",
254 | "dependencies": {
255 | "com.unity.modules.physics": "1.0.0",
256 | "com.unity.modules.terrain": "1.0.0"
257 | }
258 | },
259 | "com.unity.modules.tilemap": {
260 | "version": "1.0.0",
261 | "depth": 0,
262 | "source": "builtin",
263 | "dependencies": {
264 | "com.unity.modules.physics2d": "1.0.0"
265 | }
266 | },
267 | "com.unity.modules.ui": {
268 | "version": "1.0.0",
269 | "depth": 0,
270 | "source": "builtin",
271 | "dependencies": {}
272 | },
273 | "com.unity.modules.uielements": {
274 | "version": "1.0.0",
275 | "depth": 0,
276 | "source": "builtin",
277 | "dependencies": {
278 | "com.unity.modules.ui": "1.0.0",
279 | "com.unity.modules.imgui": "1.0.0",
280 | "com.unity.modules.jsonserialize": "1.0.0",
281 | "com.unity.modules.uielementsnative": "1.0.0"
282 | }
283 | },
284 | "com.unity.modules.uielementsnative": {
285 | "version": "1.0.0",
286 | "depth": 1,
287 | "source": "builtin",
288 | "dependencies": {
289 | "com.unity.modules.ui": "1.0.0",
290 | "com.unity.modules.imgui": "1.0.0",
291 | "com.unity.modules.jsonserialize": "1.0.0"
292 | }
293 | },
294 | "com.unity.modules.umbra": {
295 | "version": "1.0.0",
296 | "depth": 0,
297 | "source": "builtin",
298 | "dependencies": {}
299 | },
300 | "com.unity.modules.unityanalytics": {
301 | "version": "1.0.0",
302 | "depth": 0,
303 | "source": "builtin",
304 | "dependencies": {
305 | "com.unity.modules.unitywebrequest": "1.0.0",
306 | "com.unity.modules.jsonserialize": "1.0.0"
307 | }
308 | },
309 | "com.unity.modules.unitywebrequest": {
310 | "version": "1.0.0",
311 | "depth": 0,
312 | "source": "builtin",
313 | "dependencies": {}
314 | },
315 | "com.unity.modules.unitywebrequestassetbundle": {
316 | "version": "1.0.0",
317 | "depth": 0,
318 | "source": "builtin",
319 | "dependencies": {
320 | "com.unity.modules.assetbundle": "1.0.0",
321 | "com.unity.modules.unitywebrequest": "1.0.0"
322 | }
323 | },
324 | "com.unity.modules.unitywebrequestaudio": {
325 | "version": "1.0.0",
326 | "depth": 0,
327 | "source": "builtin",
328 | "dependencies": {
329 | "com.unity.modules.unitywebrequest": "1.0.0",
330 | "com.unity.modules.audio": "1.0.0"
331 | }
332 | },
333 | "com.unity.modules.unitywebrequesttexture": {
334 | "version": "1.0.0",
335 | "depth": 0,
336 | "source": "builtin",
337 | "dependencies": {
338 | "com.unity.modules.unitywebrequest": "1.0.0",
339 | "com.unity.modules.imageconversion": "1.0.0"
340 | }
341 | },
342 | "com.unity.modules.unitywebrequestwww": {
343 | "version": "1.0.0",
344 | "depth": 0,
345 | "source": "builtin",
346 | "dependencies": {
347 | "com.unity.modules.unitywebrequest": "1.0.0",
348 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0",
349 | "com.unity.modules.unitywebrequestaudio": "1.0.0",
350 | "com.unity.modules.audio": "1.0.0",
351 | "com.unity.modules.assetbundle": "1.0.0",
352 | "com.unity.modules.imageconversion": "1.0.0"
353 | }
354 | },
355 | "com.unity.modules.vehicles": {
356 | "version": "1.0.0",
357 | "depth": 0,
358 | "source": "builtin",
359 | "dependencies": {
360 | "com.unity.modules.physics": "1.0.0"
361 | }
362 | },
363 | "com.unity.modules.video": {
364 | "version": "1.0.0",
365 | "depth": 0,
366 | "source": "builtin",
367 | "dependencies": {
368 | "com.unity.modules.audio": "1.0.0",
369 | "com.unity.modules.ui": "1.0.0",
370 | "com.unity.modules.unitywebrequest": "1.0.0"
371 | }
372 | },
373 | "com.unity.modules.vr": {
374 | "version": "1.0.0",
375 | "depth": 0,
376 | "source": "builtin",
377 | "dependencies": {
378 | "com.unity.modules.jsonserialize": "1.0.0",
379 | "com.unity.modules.physics": "1.0.0",
380 | "com.unity.modules.xr": "1.0.0"
381 | }
382 | },
383 | "com.unity.modules.wind": {
384 | "version": "1.0.0",
385 | "depth": 0,
386 | "source": "builtin",
387 | "dependencies": {}
388 | },
389 | "com.unity.modules.xr": {
390 | "version": "1.0.0",
391 | "depth": 0,
392 | "source": "builtin",
393 | "dependencies": {
394 | "com.unity.modules.physics": "1.0.0",
395 | "com.unity.modules.jsonserialize": "1.0.0",
396 | "com.unity.modules.subsystems": "1.0.0"
397 | }
398 | }
399 | }
400 | }
401 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBX/Utils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Text.RegularExpressions;
5 | using System.IO;
6 |
7 | namespace Strings.iOS.Xcode.PBX
8 | {
9 | internal class GUIDToCommentMap
10 | {
11 | private Dictionary m_Dict = new Dictionary();
12 |
13 | public string this[string guid]
14 | {
15 | get {
16 | if (m_Dict.ContainsKey(guid))
17 | return m_Dict[guid];
18 | return null;
19 | }
20 | }
21 |
22 | public void Add(string guid, string comment)
23 | {
24 | if (m_Dict.ContainsKey(guid))
25 | return;
26 | m_Dict.Add(guid, comment);
27 | }
28 |
29 | public void Remove(string guid)
30 | {
31 | m_Dict.Remove(guid);
32 | }
33 |
34 | public string Write(string guid)
35 | {
36 | string comment = this[guid];
37 | if (comment == null)
38 | return guid;
39 | return String.Format("{0} /* {1} */", guid, comment);
40 | }
41 |
42 | public void WriteStringBuilder(StringBuilder sb, string guid)
43 | {
44 | string comment = this[guid];
45 | if (comment == null)
46 | sb.Append(guid);
47 | else
48 | {
49 | // {0} /* {1} */
50 | sb.Append(guid).Append(" /* ").Append(comment).Append(" */");
51 | }
52 | }
53 | }
54 |
55 | internal class PBXGUID
56 | {
57 | internal delegate string GuidGenerator();
58 |
59 | // We allow changing Guid generator to make testing of PBXProject possible
60 | private static GuidGenerator guidGenerator = DefaultGuidGenerator;
61 |
62 | internal static string DefaultGuidGenerator()
63 | {
64 | return Guid.NewGuid().ToString("N").Substring(8).ToUpper();
65 | }
66 |
67 | internal static void SetGuidGenerator(GuidGenerator generator)
68 | {
69 | guidGenerator = generator;
70 | }
71 |
72 | // Generates a GUID.
73 | public static string Generate()
74 | {
75 | return guidGenerator();
76 | }
77 | }
78 |
79 | internal class PBXRegex
80 | {
81 | public static string GuidRegexString = "[A-Fa-f0-9]{24}";
82 | }
83 |
84 | internal class PBXStream
85 | {
86 | static bool DontNeedQuotes(string src)
87 | {
88 | // using a regex instead of explicit matching slows down common cases by 40%
89 | if (src.Length == 0)
90 | return false;
91 |
92 | bool hasSlash = false;
93 | for (int i = 0; i < src.Length; ++i)
94 | {
95 | char c = src[i];
96 | if (Char.IsLetterOrDigit(c) || c == '.' || c == '*' || c == '_')
97 | continue;
98 | if (c == '/')
99 | {
100 | hasSlash = true;
101 | continue;
102 | }
103 | return false;
104 | }
105 | if (hasSlash)
106 | {
107 | if (src.Contains("//") || src.Contains("/*") || src.Contains("*/"))
108 | return false;
109 | }
110 | return true;
111 | }
112 |
113 | // Quotes the given string if it contains special characters. Note: if the string already
114 | // contains quotes, then they are escaped and the entire string quoted again
115 | public static string QuoteStringIfNeeded(string src)
116 | {
117 | if (DontNeedQuotes(src))
118 | return src;
119 | return "\"" + src.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n") + "\"";
120 | }
121 |
122 | // If the given string is quoted, removes the quotes and unescapes any quotes within the string
123 | public static string UnquoteString(string src)
124 | {
125 | if (!src.StartsWith("\"") || !src.EndsWith("\""))
126 | return src;
127 | return src.Substring(1, src.Length - 2).Replace("\\\\", "\u569f").Replace("\\\"", "\"")
128 | .Replace("\\n", "\n").Replace("\u569f", "\\"); // U+569f is a rarely used Chinese character
129 | }
130 | }
131 |
132 | internal enum PBXFileType
133 | {
134 | NotBuildable,
135 | Framework,
136 | Source,
137 | Resource,
138 | CopyFile
139 | }
140 |
141 | internal class FileTypeUtils
142 | {
143 | internal class FileTypeDesc
144 | {
145 | public FileTypeDesc(string typeName, PBXFileType type)
146 | {
147 | this.name = typeName;
148 | this.type = type;
149 | this.isExplicit = false;
150 | }
151 |
152 | public FileTypeDesc(string typeName, PBXFileType type, bool isExplicit)
153 | {
154 | this.name = typeName;
155 | this.type = type;
156 | this.isExplicit = isExplicit;
157 | }
158 |
159 | public string name;
160 | public PBXFileType type;
161 | public bool isExplicit;
162 | }
163 |
164 | private static readonly Dictionary types =
165 | new Dictionary
166 | {
167 | { "a", new FileTypeDesc("archive.ar", PBXFileType.Framework) },
168 | { "app", new FileTypeDesc("wrapper.application", PBXFileType.NotBuildable, true) },
169 | { "appex", new FileTypeDesc("wrapper.app-extension", PBXFileType.CopyFile) },
170 | { "bin", new FileTypeDesc("archive.macbinary", PBXFileType.Resource) },
171 | { "s", new FileTypeDesc("sourcecode.asm", PBXFileType.Source) },
172 | { "c", new FileTypeDesc("sourcecode.c.c", PBXFileType.Source) },
173 | { "cc", new FileTypeDesc("sourcecode.cpp.cpp", PBXFileType.Source) },
174 | { "cpp", new FileTypeDesc("sourcecode.cpp.cpp", PBXFileType.Source) },
175 | { "swift", new FileTypeDesc("sourcecode.swift", PBXFileType.Source) },
176 | { "dll", new FileTypeDesc("file", PBXFileType.NotBuildable) },
177 | { "framework", new FileTypeDesc("wrapper.framework", PBXFileType.Framework) },
178 | { "h", new FileTypeDesc("sourcecode.c.h", PBXFileType.NotBuildable) },
179 | { "pch", new FileTypeDesc("sourcecode.c.h", PBXFileType.NotBuildable) },
180 | { "icns", new FileTypeDesc("image.icns", PBXFileType.Resource) },
181 | { "xcassets", new FileTypeDesc("folder.assetcatalog", PBXFileType.Resource) },
182 | { "inc", new FileTypeDesc("sourcecode.inc", PBXFileType.NotBuildable) },
183 | { "m", new FileTypeDesc("sourcecode.c.objc", PBXFileType.Source) },
184 | { "mm", new FileTypeDesc("sourcecode.cpp.objcpp", PBXFileType.Source ) },
185 | { "nib", new FileTypeDesc("wrapper.nib", PBXFileType.Resource) },
186 | { "plist", new FileTypeDesc("text.plist.xml", PBXFileType.Resource) },
187 | { "png", new FileTypeDesc("image.png", PBXFileType.Resource) },
188 | { "rtf", new FileTypeDesc("text.rtf", PBXFileType.Resource) },
189 | { "tiff", new FileTypeDesc("image.tiff", PBXFileType.Resource) },
190 | { "txt", new FileTypeDesc("text", PBXFileType.Resource) },
191 | { "json", new FileTypeDesc("text.json", PBXFileType.Resource) },
192 | { "xcodeproj", new FileTypeDesc("wrapper.pb-project", PBXFileType.NotBuildable) },
193 | { "xib", new FileTypeDesc("file.xib", PBXFileType.Resource) },
194 | { "strings", new FileTypeDesc("text.plist.strings", PBXFileType.Resource) },
195 | { "storyboard",new FileTypeDesc("file.storyboard", PBXFileType.Resource) },
196 | { "bundle", new FileTypeDesc("wrapper.plug-in", PBXFileType.Resource) },
197 | { "dylib", new FileTypeDesc("compiled.mach-o.dylib", PBXFileType.Framework) },
198 | { "tbd", new FileTypeDesc("sourcecode.text-based-dylib-definition", PBXFileType.Framework) }
199 | };
200 |
201 | public static string TrimExtension(string ext)
202 | {
203 | return ext.TrimStart('.');
204 | }
205 |
206 | public static bool IsKnownExtension(string ext)
207 | {
208 | ext = TrimExtension(ext);
209 | return types.ContainsKey(ext);
210 | }
211 |
212 | internal static bool IsFileTypeExplicit(string ext)
213 | {
214 | ext = TrimExtension(ext);
215 | if (types.ContainsKey(ext))
216 | return types[ext].isExplicit;
217 | return false;
218 | }
219 |
220 | public static PBXFileType GetFileType(string ext, bool isFolderRef)
221 | {
222 | ext = TrimExtension(ext);
223 | if (isFolderRef)
224 | return PBXFileType.Resource;
225 | if (!types.ContainsKey(ext))
226 | return PBXFileType.Resource;
227 | return types[ext].type;
228 | }
229 |
230 | public static string GetTypeName(string ext)
231 | {
232 | ext = TrimExtension(ext);
233 | if (types.ContainsKey(ext))
234 | return types[ext].name;
235 | // Xcode actually checks the file contents to determine the file type.
236 | // Text files have "text" type and all other files have "file" type.
237 | // Since we can't reasonably determine whether the file in question is
238 | // a text file, we just take the safe route and return "file" type.
239 | return "file";
240 | }
241 |
242 | public static bool IsBuildableFile(string ext)
243 | {
244 | ext = TrimExtension(ext);
245 | if (!types.ContainsKey(ext))
246 | return true;
247 | if (types[ext].type != PBXFileType.NotBuildable)
248 | return true;
249 | return false;
250 | }
251 |
252 | public static bool IsBuildable(string ext, bool isFolderReference)
253 | {
254 | ext = TrimExtension(ext);
255 | if (isFolderReference)
256 | return true;
257 | return IsBuildableFile(ext);
258 | }
259 |
260 | private static readonly Dictionary sourceTree = new Dictionary
261 | {
262 | { PBXSourceTree.Absolute, "" },
263 | { PBXSourceTree.Group, "" },
264 | { PBXSourceTree.Build, "BUILT_PRODUCTS_DIR" },
265 | { PBXSourceTree.Developer, "DEVELOPER_DIR" },
266 | { PBXSourceTree.Sdk, "SDKROOT" },
267 | { PBXSourceTree.Source, "SOURCE_ROOT" },
268 | };
269 |
270 | private static readonly Dictionary stringToSourceTreeMap = new Dictionary
271 | {
272 | { "", PBXSourceTree.Absolute },
273 | { "", PBXSourceTree.Group },
274 | { "BUILT_PRODUCTS_DIR", PBXSourceTree.Build },
275 | { "DEVELOPER_DIR", PBXSourceTree.Developer },
276 | { "SDKROOT", PBXSourceTree.Sdk },
277 | { "SOURCE_ROOT", PBXSourceTree.Source },
278 | };
279 |
280 | internal static string SourceTreeDesc(PBXSourceTree tree)
281 | {
282 | return sourceTree[tree];
283 | }
284 |
285 | // returns PBXSourceTree.Source on error
286 | internal static PBXSourceTree ParseSourceTree(string tree)
287 | {
288 | if (stringToSourceTreeMap.ContainsKey(tree))
289 | return stringToSourceTreeMap[tree];
290 | return PBXSourceTree.Source;
291 | }
292 |
293 | internal static List AllAbsoluteSourceTrees()
294 | {
295 | return new List{PBXSourceTree.Absolute, PBXSourceTree.Build,
296 | PBXSourceTree.Developer, PBXSourceTree.Sdk, PBXSourceTree.Source};
297 | }
298 | }
299 |
300 | } // UnityEditor.iOS.Xcode
301 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PlistParser.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Xml;
6 | using System.Xml.Linq;
7 | using System.Xml.XPath;
8 |
9 | namespace Strings.iOS.Xcode
10 | {
11 |
12 | public class PlistElement
13 | {
14 | protected PlistElement() {}
15 |
16 | // convenience methods
17 | public string AsString() { return ((PlistElementString)this).value; }
18 | public int AsInteger() { return ((PlistElementInteger)this).value; }
19 | public bool AsBoolean() { return ((PlistElementBoolean)this).value; }
20 | public PlistElementArray AsArray() { return (PlistElementArray)this; }
21 | public PlistElementDict AsDict() { return (PlistElementDict)this; }
22 |
23 | public PlistElement this[string key]
24 | {
25 | get { return AsDict()[key]; }
26 | set { AsDict()[key] = value; }
27 | }
28 | }
29 |
30 | public class PlistElementString : PlistElement
31 | {
32 | public PlistElementString(string v) { value = v; }
33 |
34 | public string value;
35 | }
36 |
37 | public class PlistElementInteger : PlistElement
38 | {
39 | public PlistElementInteger(int v) { value = v; }
40 |
41 | public int value;
42 | }
43 |
44 | public class PlistElementBoolean : PlistElement
45 | {
46 | public PlistElementBoolean(bool v) { value = v; }
47 |
48 | public bool value;
49 | }
50 |
51 | public class PlistElementDict : PlistElement
52 | {
53 | public PlistElementDict() : base() {}
54 |
55 | private SortedDictionary m_PrivateValue = new SortedDictionary();
56 | public IDictionary values { get { return m_PrivateValue; }}
57 |
58 | new public PlistElement this[string key]
59 | {
60 | get {
61 | if (values.ContainsKey(key))
62 | return values[key];
63 | return null;
64 | }
65 | set { this.values[key] = value; }
66 | }
67 |
68 |
69 | // convenience methods
70 | public void SetInteger(string key, int val)
71 | {
72 | values[key] = new PlistElementInteger(val);
73 | }
74 |
75 | public void SetString(string key, string val)
76 | {
77 | values[key] = new PlistElementString(val);
78 | }
79 |
80 | public void SetBoolean(string key, bool val)
81 | {
82 | values[key] = new PlistElementBoolean(val);
83 | }
84 |
85 | public PlistElementArray CreateArray(string key)
86 | {
87 | var v = new PlistElementArray();
88 | values[key] = v;
89 | return v;
90 | }
91 |
92 | public PlistElementDict CreateDict(string key)
93 | {
94 | var v = new PlistElementDict();
95 | values[key] = v;
96 | return v;
97 | }
98 | }
99 |
100 | public class PlistElementArray : PlistElement
101 | {
102 | public PlistElementArray() : base() {}
103 | public List values = new List();
104 |
105 | // convenience methods
106 | public void AddString(string val)
107 | {
108 | values.Add(new PlistElementString(val));
109 | }
110 |
111 | public void AddInteger(int val)
112 | {
113 | values.Add(new PlistElementInteger(val));
114 | }
115 |
116 | public void AddBoolean(bool val)
117 | {
118 | values.Add(new PlistElementBoolean(val));
119 | }
120 |
121 | public PlistElementArray AddArray()
122 | {
123 | var v = new PlistElementArray();
124 | values.Add(v);
125 | return v;
126 | }
127 |
128 | public PlistElementDict AddDict()
129 | {
130 | var v = new PlistElementDict();
131 | values.Add(v);
132 | return v;
133 | }
134 | }
135 |
136 | public class PlistDocument
137 | {
138 | public PlistElementDict root;
139 | public string version;
140 |
141 | public PlistDocument()
142 | {
143 | root = new PlistElementDict();
144 | version = "1.0";
145 | }
146 |
147 | // Parses a string that contains a XML file. No validation is done.
148 | internal static XDocument ParseXmlNoDtd(string text)
149 | {
150 | XmlReaderSettings settings = new XmlReaderSettings();
151 | settings.ProhibitDtd = false;
152 | settings.XmlResolver = null; // prevent DTD download
153 |
154 | XmlReader xmlReader = XmlReader.Create(new StringReader(text), settings);
155 | return XDocument.Load(xmlReader);
156 | }
157 |
158 | // LINQ serializes XML DTD declaration with an explicit empty 'internal subset'
159 | // (a pair of square brackets at the end of Doctype declaration).
160 | // Even though this is valid XML, XCode does not like it, hence this workaround.
161 | internal static string CleanDtdToString(XDocument doc)
162 | {
163 | // LINQ does not support changing the DTD of existing XDocument instances,
164 | // so we create a dummy document for printing of the Doctype declaration.
165 | // A single dummy element is added to force LINQ not to omit the declaration.
166 | // Also, utf-8 encoding is forced since this is the encoding we use when writing to file in UpdateInfoPlist.
167 | if (doc.DocumentType != null)
168 | {
169 | XDocument tmpDoc =
170 | new XDocument(new XDeclaration("1.0", "utf-8", null),
171 | new XDocumentType(doc.DocumentType.Name, doc.DocumentType.PublicId, doc.DocumentType.SystemId, null),
172 | new XElement(doc.Root.Name));
173 | return "" + tmpDoc.Declaration + "\n" + tmpDoc.DocumentType + "\n" + doc.Root;
174 | }
175 | else
176 | {
177 | XDocument tmpDoc = new XDocument(new XDeclaration("1.0", "utf-8", null), new XElement(doc.Root.Name));
178 | return "" + tmpDoc.Declaration + Environment.NewLine + doc.Root;
179 | }
180 | }
181 |
182 | private static string GetText(XElement xml)
183 | {
184 | return String.Join("", xml.Nodes().OfType().Select(x => x.Value).ToArray());
185 | }
186 |
187 | private static PlistElement ReadElement(XElement xml)
188 | {
189 | switch (xml.Name.LocalName)
190 | {
191 | case "dict":
192 | {
193 | List children = xml.Elements().ToList();
194 | var el = new PlistElementDict();
195 |
196 | if (children.Count % 2 == 1)
197 | throw new Exception("Malformed plist file");
198 |
199 | for (int i = 0; i < children.Count - 1; i++)
200 | {
201 | if (children[i].Name != "key")
202 | throw new Exception("Malformed plist file");
203 | string key = GetText(children[i]).Trim();
204 | var newChild = ReadElement(children[i+1]);
205 | if (newChild != null)
206 | {
207 | i++;
208 | el[key] = newChild;
209 | }
210 | }
211 | return el;
212 | }
213 | case "array":
214 | {
215 | List children = xml.Elements().ToList();
216 | var el = new PlistElementArray();
217 |
218 | foreach (var childXml in children)
219 | {
220 | var newChild = ReadElement(childXml);
221 | if (newChild != null)
222 | el.values.Add(newChild);
223 | }
224 | return el;
225 | }
226 | case "string":
227 | return new PlistElementString(GetText(xml));
228 | case "integer":
229 | {
230 | int r;
231 | if (int.TryParse(GetText(xml), out r))
232 | return new PlistElementInteger(r);
233 | return null;
234 | }
235 | case "true":
236 | return new PlistElementBoolean(true);
237 | case "false":
238 | return new PlistElementBoolean(false);
239 | default:
240 | return null;
241 | }
242 | }
243 |
244 | public void Create()
245 | {
246 | const string doc = "" +
247 | "" +
248 | "" +
249 | "" +
250 | "" +
251 | "";
252 | ReadFromString(doc);
253 | }
254 |
255 | public void ReadFromFile(string path)
256 | {
257 | ReadFromString(File.ReadAllText(path));
258 | }
259 |
260 | public void ReadFromStream(TextReader tr)
261 | {
262 | ReadFromString(tr.ReadToEnd());
263 | }
264 |
265 | public void ReadFromString(string text)
266 | {
267 | XDocument doc = ParseXmlNoDtd(text);
268 | version = (string) doc.Root.Attribute("version");
269 | XElement xml = doc.XPathSelectElement("plist/dict");
270 |
271 | var dict = ReadElement(xml);
272 | if (dict == null)
273 | throw new Exception("Error parsing plist file");
274 | root = dict as PlistElementDict;
275 | if (root == null)
276 | throw new Exception("Malformed plist file");
277 | }
278 |
279 | private static XElement WriteElement(PlistElement el)
280 | {
281 | if (el is PlistElementBoolean)
282 | {
283 | var realEl = el as PlistElementBoolean;
284 | return new XElement(realEl.value ? "true" : "false");
285 | }
286 | if (el is PlistElementInteger)
287 | {
288 | var realEl = el as PlistElementInteger;
289 | return new XElement("integer", realEl.value.ToString());
290 | }
291 | if (el is PlistElementString)
292 | {
293 | var realEl = el as PlistElementString;
294 | return new XElement("string", realEl.value);
295 | }
296 | if (el is PlistElementDict)
297 | {
298 | var realEl = el as PlistElementDict;
299 | var dictXml = new XElement("dict");
300 | foreach (var kv in realEl.values)
301 | {
302 | var keyXml = new XElement("key", kv.Key);
303 | var valueXml = WriteElement(kv.Value);
304 | if (valueXml != null)
305 | {
306 | dictXml.Add(keyXml);
307 | dictXml.Add(valueXml);
308 | }
309 | }
310 | return dictXml;
311 | }
312 | if (el is PlistElementArray)
313 | {
314 | var realEl = el as PlistElementArray;
315 | var arrayXml = new XElement("array");
316 | foreach (var v in realEl.values)
317 | {
318 | var elXml = WriteElement(v);
319 | if (elXml != null)
320 | arrayXml.Add(elXml);
321 | }
322 | return arrayXml;
323 | }
324 | return null;
325 | }
326 |
327 | public void WriteToFile(string path)
328 | {
329 | System.Text.Encoding utf8WithoutBom = new System.Text.UTF8Encoding(false);
330 | File.WriteAllText(path, WriteToString(), utf8WithoutBom);
331 | }
332 |
333 | public void WriteToStream(TextWriter tw)
334 | {
335 | tw.Write(WriteToString());
336 | }
337 |
338 | public string WriteToString()
339 | {
340 | var el = WriteElement(root);
341 | var rootEl = new XElement("plist");
342 | rootEl.Add(new XAttribute("version", version));
343 | rootEl.Add(el);
344 |
345 | var doc = new XDocument();
346 | doc.Add(rootEl);
347 | return CleanDtdToString(doc).Replace("\r\n", "\n");
348 | }
349 | }
350 |
351 | } // namespace UnityEditor.iOS.XCode
352 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/PBXProjectExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Text;
3 | using System.Text.RegularExpressions;
4 | using System.IO;
5 | using System;
6 | using Strings.iOS.Xcode.PBX;
7 |
8 | namespace Strings.iOS.Xcode.Extensions
9 | {
10 | /* This class implements a number of static methods for performing common tasks
11 | on xcode projects.
12 | TODO: Make sure enough stuff is exposed so that it's possible to perform the tasks
13 | without using internal APIs
14 | */
15 | public static class PBXProjectExtensions
16 | {
17 | // Create a wrapper class so that collection initializers work and we can have a
18 | // compact notation. Note that we can't use Dictionary because the keys may be duplicate
19 | internal class FlagList : List>
20 | {
21 | public void Add(string flag, string value)
22 | {
23 | Add(new KeyValuePair(flag, value));
24 | }
25 | }
26 |
27 | internal static FlagList appExtensionReleaseBuildFlags = new FlagList
28 | {
29 | // { "INFOPLIST_FILE", },
30 | { "LD_RUNPATH_SEARCH_PATHS", "$(inherited)" },
31 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks" },
32 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/../../Frameworks" },
33 | // { "PRODUCT_BUNDLE_IDENTIFIER", "" },
34 | { "PRODUCT_NAME", "$(TARGET_NAME)" },
35 | { "SKIP_INSTALL", "YES" },
36 | };
37 |
38 | internal static FlagList appExtensionDebugBuildFlags = new FlagList
39 | {
40 | // { "INFOPLIST_FILE", },
41 | { "LD_RUNPATH_SEARCH_PATHS", "$(inherited)" },
42 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks" },
43 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/../../Frameworks" },
44 | // { "PRODUCT_BUNDLE_IDENTIFIER", "" },
45 | { "PRODUCT_NAME", "$(TARGET_NAME)" },
46 | { "SKIP_INSTALL", "YES" },
47 | };
48 |
49 | internal static FlagList watchExtensionReleaseBuildFlags = new FlagList
50 | {
51 | { "ASSETCATALOG_COMPILER_COMPLICATION_NAME", "Complication" },
52 | { "CLANG_ANALYZER_NONNULL", "YES" },
53 | { "CLANG_WARN_DOCUMENTATION_COMMENTS", "YES" },
54 | { "CLANG_WARN_INFINITE_RECURSION", "YES" },
55 | { "CLANG_WARN_SUSPICIOUS_MOVE", "YES" },
56 | { "DEBUG_INFORMATION_FORMAT", "dwarf-with-dsym" },
57 | { "GCC_NO_COMMON_BLOCKS", "YES" },
58 | //{ "INFOPLIST_FILE", "" },
59 | { "LD_RUNPATH_SEARCH_PATHS", "$(inherited)" },
60 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks" },
61 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/../../Frameworks" },
62 | // { "PRODUCT_BUNDLE_IDENTIFIER", "" },
63 | { "PRODUCT_NAME", "${TARGET_NAME}" },
64 | { "SDKROOT", "watchos" },
65 | { "SKIP_INSTALL", "YES" },
66 | { "TARGETED_DEVICE_FAMILY", "4" },
67 | { "WATCHOS_DEPLOYMENT_TARGET", "3.1" },
68 | // the following are needed to override project settings in Unity Xcode project
69 | { "ARCHS", "$(ARCHS_STANDARD)" },
70 | { "SUPPORTED_PLATFORMS", "watchos" },
71 | { "SUPPORTED_PLATFORMS", "watchsimulator" },
72 | };
73 |
74 | internal static FlagList watchExtensionDebugBuildFlags = new FlagList
75 | {
76 | { "ASSETCATALOG_COMPILER_COMPLICATION_NAME", "Complication" },
77 | { "CLANG_ANALYZER_NONNULL", "YES" },
78 | { "CLANG_WARN_DOCUMENTATION_COMMENTS", "YES" },
79 | { "CLANG_WARN_INFINITE_RECURSION", "YES" },
80 | { "CLANG_WARN_SUSPICIOUS_MOVE", "YES" },
81 | { "DEBUG_INFORMATION_FORMAT", "dwarf" },
82 | { "ENABLE_TESTABILITY", "YES" },
83 | { "GCC_NO_COMMON_BLOCKS", "YES" },
84 | // { "INFOPLIST_FILE", "" },
85 | { "LD_RUNPATH_SEARCH_PATHS", "$(inherited)" },
86 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/Frameworks" },
87 | { "LD_RUNPATH_SEARCH_PATHS", "@executable_path/../../Frameworks" },
88 | // { "PRODUCT_BUNDLE_IDENTIFIER", "" },
89 | { "PRODUCT_NAME", "${TARGET_NAME}" },
90 | { "SDKROOT", "watchos" },
91 | { "SKIP_INSTALL", "YES" },
92 | { "TARGETED_DEVICE_FAMILY", "4" },
93 | { "WATCHOS_DEPLOYMENT_TARGET", "3.1" },
94 | // the following are needed to override project settings in Unity Xcode project
95 | { "ARCHS", "$(ARCHS_STANDARD)" },
96 | { "SUPPORTED_PLATFORMS", "watchos" },
97 | { "SUPPORTED_PLATFORMS", "watchsimulator" },
98 | };
99 |
100 | internal static FlagList watchAppReleaseBuildFlags = new FlagList
101 | {
102 | { "ASSETCATALOG_COMPILER_APPICON_NAME", "AppIcon" },
103 | { "CLANG_ANALYZER_NONNULL", "YES" },
104 | { "CLANG_WARN_DOCUMENTATION_COMMENTS", "YES" },
105 | { "CLANG_WARN_INFINITE_RECURSION", "YES" },
106 | { "CLANG_WARN_SUSPICIOUS_MOVE", "YES" },
107 | { "DEBUG_INFORMATION_FORMAT", "dwarf-with-dsym" },
108 | { "GCC_NO_COMMON_BLOCKS", "YES" },
109 | //{ "IBSC_MODULE", "the extension target name with ' ' replaced with '_'" },
110 | //{ "INFOPLIST_FILE", "" },
111 | //{ "PRODUCT_BUNDLE_IDENTIFIER", "" },
112 | { "PRODUCT_NAME", "$(TARGET_NAME)" },
113 | { "SDKROOT", "watchos" },
114 | { "SKIP_INSTALL", "YES" },
115 | { "TARGETED_DEVICE_FAMILY", "4" },
116 | { "WATCHOS_DEPLOYMENT_TARGET", "3.1" },
117 | // the following are needed to override project settings in Unity Xcode project
118 | { "ARCHS", "$(ARCHS_STANDARD)" },
119 | { "SUPPORTED_PLATFORMS", "watchos" },
120 | { "SUPPORTED_PLATFORMS", "watchsimulator" },
121 | };
122 |
123 | internal static FlagList watchAppDebugBuildFlags = new FlagList
124 | {
125 | { "ASSETCATALOG_COMPILER_APPICON_NAME", "AppIcon" },
126 | { "CLANG_ANALYZER_NONNULL", "YES" },
127 | { "CLANG_WARN_DOCUMENTATION_COMMENTS", "YES" },
128 | { "CLANG_WARN_INFINITE_RECURSION", "YES" },
129 | { "CLANG_WARN_SUSPICIOUS_MOVE", "YES" },
130 | { "DEBUG_INFORMATION_FORMAT", "dwarf" },
131 | { "ENABLE_TESTABILITY", "YES" },
132 | { "GCC_NO_COMMON_BLOCKS", "YES" },
133 | //{ "IBSC_MODULE", "the extension target name with ' ' replaced with '_'" },
134 | //{ "INFOPLIST_FILE", "" },
135 | //{ "PRODUCT_BUNDLE_IDENTIFIER", "" },
136 | { "PRODUCT_NAME", "$(TARGET_NAME)" },
137 | { "SDKROOT", "watchos" },
138 | { "SKIP_INSTALL", "YES" },
139 | { "TARGETED_DEVICE_FAMILY", "4" },
140 | { "WATCHOS_DEPLOYMENT_TARGET", "3.1" },
141 | // the following are needed to override project settings in Unity Xcode project
142 | { "ARCHS", "$(ARCHS_STANDARD)" },
143 | { "SUPPORTED_PLATFORMS", "watchos" },
144 | { "SUPPORTED_PLATFORMS", "watchsimulator" },
145 | };
146 |
147 | static void SetBuildFlagsFromDict(this PBXProject proj, string configGuid, IEnumerable> data)
148 | {
149 | foreach (var kv in data)
150 | proj.AddBuildPropertyForConfig(configGuid, kv.Key, kv.Value);
151 | }
152 |
153 | internal static void SetDefaultAppExtensionReleaseBuildFlags(this PBXProject proj, string configGuid)
154 | {
155 | SetBuildFlagsFromDict(proj, configGuid, appExtensionReleaseBuildFlags);
156 | }
157 |
158 | internal static void SetDefaultAppExtensionDebugBuildFlags(this PBXProject proj, string configGuid)
159 | {
160 | SetBuildFlagsFromDict(proj, configGuid, appExtensionDebugBuildFlags);
161 | }
162 |
163 | internal static void SetDefaultWatchExtensionReleaseBuildFlags(this PBXProject proj, string configGuid)
164 | {
165 | SetBuildFlagsFromDict(proj, configGuid, watchExtensionReleaseBuildFlags);
166 | }
167 |
168 | internal static void SetDefaultWatchExtensionDebugBuildFlags(this PBXProject proj, string configGuid)
169 | {
170 | SetBuildFlagsFromDict(proj, configGuid, watchExtensionDebugBuildFlags);
171 | }
172 |
173 | internal static void SetDefaultWatchAppReleaseBuildFlags(this PBXProject proj, string configGuid)
174 | {
175 | SetBuildFlagsFromDict(proj, configGuid, watchAppReleaseBuildFlags);
176 | }
177 |
178 | internal static void SetDefaultWatchAppDebugBuildFlags(this PBXProject proj, string configGuid)
179 | {
180 | SetBuildFlagsFromDict(proj, configGuid, watchAppDebugBuildFlags);
181 | }
182 |
183 | ///
184 | /// Creates an app extension.
185 | ///
186 | /// The GUID of the new target.
187 | /// A project passed as this argument.
188 | /// The GUID of the main target to link the app to.
189 | /// The name of the app extension.
190 | /// The bundle ID of the app extension. The bundle ID must be
191 | /// prefixed with the parent app bundle ID.
192 | /// Path to the app extension Info.plist document.
193 | public static string AddAppExtension(this PBXProject proj, string mainTargetGuid,
194 | string name, string bundleId, string infoPlistPath)
195 | {
196 | string ext = ".appex";
197 | var newTargetGuid = proj.AddTarget(name, ext, "com.apple.product-type.app-extension");
198 |
199 | foreach (var configName in proj.BuildConfigNames())
200 | {
201 | var configGuid = proj.BuildConfigByName(newTargetGuid, configName);
202 | if (configName.Contains("Debug"))
203 | SetDefaultAppExtensionDebugBuildFlags(proj, configGuid);
204 | else
205 | SetDefaultAppExtensionReleaseBuildFlags(proj, configGuid);
206 | proj.SetBuildPropertyForConfig(configGuid, "INFOPLIST_FILE", infoPlistPath);
207 | proj.SetBuildPropertyForConfig(configGuid, "PRODUCT_BUNDLE_IDENTIFIER", bundleId);
208 | }
209 |
210 | proj.AddSourcesBuildPhase(newTargetGuid);
211 | proj.AddResourcesBuildPhase(newTargetGuid);
212 | proj.AddFrameworksBuildPhase(newTargetGuid);
213 | string copyFilesPhaseGuid = proj.AddCopyFilesBuildPhase(mainTargetGuid, "Embed App Extensions", "", "13");
214 | proj.AddFileToBuildSection(mainTargetGuid, copyFilesPhaseGuid, proj.GetTargetProductFileRef(newTargetGuid));
215 |
216 | proj.AddTargetDependency(mainTargetGuid, newTargetGuid);
217 |
218 | return newTargetGuid;
219 | }
220 |
221 | ///
222 | /// Creates a watch application.
223 | ///
224 | /// The GUID of the new target.
225 | /// A project passed as this argument.
226 | /// The GUID of the main target to link the watch app to.
227 | /// The GUID of watch extension as returned by [[AddWatchExtension()]].
228 | /// The name of the watch app. It must the same as the name of the watch extension.
229 | /// The bundle ID of the watch app.
230 | /// Path to the watch app Info.plist document.
231 | public static string AddWatchApp(this PBXProject proj, string mainTargetGuid, string watchExtensionTargetGuid,
232 | string name, string bundleId, string infoPlistPath)
233 | {
234 | var newTargetGuid = proj.AddTarget(name, ".app", "com.apple.product-type.application.watchapp2");
235 |
236 | var isbcModuleName = proj.nativeTargets[watchExtensionTargetGuid].name.Replace(" ", "_");
237 |
238 | foreach (var configName in proj.BuildConfigNames())
239 | {
240 | var configGuid = proj.BuildConfigByName(newTargetGuid, configName);
241 | if (configName.Contains("Debug"))
242 | SetDefaultWatchAppDebugBuildFlags(proj, configGuid);
243 | else
244 | SetDefaultWatchAppReleaseBuildFlags(proj, configGuid);
245 | proj.SetBuildPropertyForConfig(configGuid, "PRODUCT_BUNDLE_IDENTIFIER", bundleId);
246 | proj.SetBuildPropertyForConfig(configGuid, "INFOPLIST_FILE", infoPlistPath);
247 | proj.SetBuildPropertyForConfig(configGuid, "IBSC_MODULE", isbcModuleName);
248 | }
249 |
250 | proj.AddResourcesBuildPhase(newTargetGuid);
251 | string copyFilesGuid = proj.AddCopyFilesBuildPhase(newTargetGuid, "Embed App Extensions", "", "13");
252 | proj.AddFileToBuildSection(newTargetGuid, copyFilesGuid, proj.GetTargetProductFileRef(watchExtensionTargetGuid));
253 |
254 | string copyWatchFilesGuid = proj.AddCopyFilesBuildPhase(mainTargetGuid, "Embed Watch Content", "$(CONTENTS_FOLDER_PATH)/Watch", "16");
255 | proj.AddFileToBuildSection(mainTargetGuid, copyWatchFilesGuid, proj.GetTargetProductFileRef(newTargetGuid));
256 |
257 | proj.AddTargetDependency(newTargetGuid, watchExtensionTargetGuid);
258 | proj.AddTargetDependency(mainTargetGuid, newTargetGuid);
259 |
260 | return newTargetGuid;
261 | }
262 |
263 | ///
264 | /// Creates a watch extension.
265 | ///
266 | /// The GUID of the new target.
267 | /// A project passed as this argument.
268 | /// The GUID of the main target to link the watch extension to.
269 | /// The name of the watch extension.
270 | /// The bundle ID of the watch extension. The bundle ID must be
271 | /// prefixed with the parent watch app bundle ID.
272 | /// Path to the watch extension Info.plist document.
273 | public static string AddWatchExtension(this PBXProject proj, string mainTarget,
274 | string name, string bundleId, string infoPlistPath)
275 | {
276 | var newTargetGuid = proj.AddTarget(name, ".appex", "com.apple.product-type.watchkit2-extension");
277 |
278 | foreach (var configName in proj.BuildConfigNames())
279 | {
280 | var configGuid = proj.BuildConfigByName(newTargetGuid, configName);
281 | if (configName.Contains("Debug"))
282 | SetDefaultWatchExtensionDebugBuildFlags(proj, configGuid);
283 | else
284 | SetDefaultWatchExtensionReleaseBuildFlags(proj, configGuid);
285 | proj.SetBuildPropertyForConfig(configGuid, "PRODUCT_BUNDLE_IDENTIFIER", bundleId);
286 | proj.SetBuildPropertyForConfig(configGuid, "INFOPLIST_FILE", infoPlistPath);
287 | }
288 |
289 | proj.AddSourcesBuildPhase(newTargetGuid);
290 | proj.AddResourcesBuildPhase(newTargetGuid);
291 | proj.AddFrameworksBuildPhase(newTargetGuid);
292 |
293 | return newTargetGuid;
294 | }
295 | }
296 | } // namespace UnityEditor.iOS.Xcode
297 |
--------------------------------------------------------------------------------
/ProjectSettings/ProjectSettings.asset:
--------------------------------------------------------------------------------
1 | %YAML 1.1
2 | %TAG !u! tag:unity3d.com,2011:
3 | --- !u!129 &1
4 | PlayerSettings:
5 | m_ObjectHideFlags: 0
6 | serializedVersion: 18
7 | productGUID: f671b82672e4a4d1a83f8dbd70d548c6
8 | AndroidProfiler: 0
9 | AndroidFilterTouchesWhenObscured: 0
10 | AndroidEnableSustainedPerformanceMode: 0
11 | defaultScreenOrientation: 4
12 | targetDevice: 2
13 | useOnDemandResources: 0
14 | accelerometerFrequency: 60
15 | companyName: DefaultCompany
16 | productName: OnPostProcessBuild
17 | defaultCursor: {fileID: 0}
18 | cursorHotspot: {x: 0, y: 0}
19 | m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}
20 | m_ShowUnitySplashScreen: 1
21 | m_ShowUnitySplashLogo: 1
22 | m_SplashScreenOverlayOpacity: 1
23 | m_SplashScreenAnimation: 1
24 | m_SplashScreenLogoStyle: 1
25 | m_SplashScreenDrawMode: 0
26 | m_SplashScreenBackgroundAnimationZoom: 1
27 | m_SplashScreenLogoAnimationZoom: 1
28 | m_SplashScreenBackgroundLandscapeAspect: 1
29 | m_SplashScreenBackgroundPortraitAspect: 1
30 | m_SplashScreenBackgroundLandscapeUvs:
31 | serializedVersion: 2
32 | x: 0
33 | y: 0
34 | width: 1
35 | height: 1
36 | m_SplashScreenBackgroundPortraitUvs:
37 | serializedVersion: 2
38 | x: 0
39 | y: 0
40 | width: 1
41 | height: 1
42 | m_SplashScreenLogos: []
43 | m_VirtualRealitySplashScreen: {fileID: 0}
44 | m_HolographicTrackingLossScreen: {fileID: 0}
45 | defaultScreenWidth: 1024
46 | defaultScreenHeight: 768
47 | defaultScreenWidthWeb: 960
48 | defaultScreenHeightWeb: 600
49 | m_StereoRenderingPath: 0
50 | m_ActiveColorSpace: 0
51 | m_MTRendering: 1
52 | m_StackTraceTypes: 010000000100000001000000010000000100000001000000
53 | iosShowActivityIndicatorOnLoading: -1
54 | androidShowActivityIndicatorOnLoading: -1
55 | displayResolutionDialog: 1
56 | iosUseCustomAppBackgroundBehavior: 0
57 | iosAllowHTTPDownload: 1
58 | allowedAutorotateToPortrait: 1
59 | allowedAutorotateToPortraitUpsideDown: 1
60 | allowedAutorotateToLandscapeRight: 1
61 | allowedAutorotateToLandscapeLeft: 1
62 | useOSAutorotation: 1
63 | use32BitDisplayBuffer: 1
64 | preserveFramebufferAlpha: 0
65 | disableDepthAndStencilBuffers: 0
66 | androidStartInFullscreen: 1
67 | androidRenderOutsideSafeArea: 0
68 | androidBlitType: 0
69 | defaultIsNativeResolution: 1
70 | macRetinaSupport: 1
71 | runInBackground: 1
72 | captureSingleScreen: 0
73 | muteOtherAudioSources: 0
74 | Prepare IOS For Recording: 0
75 | Force IOS Speakers When Recording: 0
76 | deferSystemGesturesMode: 0
77 | hideHomeButton: 0
78 | submitAnalytics: 1
79 | usePlayerLog: 1
80 | bakeCollisionMeshes: 0
81 | forceSingleInstance: 0
82 | resizableWindow: 0
83 | useMacAppStoreValidation: 0
84 | macAppStoreCategory: public.app-category.games
85 | gpuSkinning: 1
86 | graphicsJobs: 0
87 | xboxPIXTextureCapture: 0
88 | xboxEnableAvatar: 0
89 | xboxEnableKinect: 0
90 | xboxEnableKinectAutoTracking: 0
91 | xboxEnableFitness: 0
92 | visibleInBackground: 1
93 | allowFullscreenSwitch: 1
94 | graphicsJobMode: 0
95 | fullscreenMode: 1
96 | xboxSpeechDB: 0
97 | xboxEnableHeadOrientation: 0
98 | xboxEnableGuest: 0
99 | xboxEnablePIXSampling: 0
100 | metalFramebufferOnly: 0
101 | xboxOneResolution: 0
102 | xboxOneSResolution: 0
103 | xboxOneXResolution: 3
104 | xboxOneMonoLoggingLevel: 0
105 | xboxOneLoggingLevel: 1
106 | xboxOneDisableEsram: 0
107 | xboxOnePresentImmediateThreshold: 0
108 | switchQueueCommandMemory: 0
109 | switchQueueControlMemory: 16384
110 | switchQueueComputeMemory: 262144
111 | switchNVNShaderPoolsGranularity: 33554432
112 | switchNVNDefaultPoolsGranularity: 16777216
113 | switchNVNOtherPoolsGranularity: 16777216
114 | vulkanEnableSetSRGBWrite: 0
115 | m_SupportedAspectRatios:
116 | 4:3: 1
117 | 5:4: 1
118 | 16:10: 1
119 | 16:9: 1
120 | Others: 1
121 | bundleVersion: 0.1
122 | preloadedAssets: []
123 | metroInputSource: 0
124 | wsaTransparentSwapchain: 0
125 | m_HolographicPauseOnTrackingLoss: 1
126 | xboxOneDisableKinectGpuReservation: 1
127 | xboxOneEnable7thCore: 1
128 | isWsaHolographicRemotingEnabled: 0
129 | vrSettings:
130 | cardboard:
131 | depthFormat: 0
132 | enableTransitionView: 0
133 | daydream:
134 | depthFormat: 0
135 | useSustainedPerformanceMode: 0
136 | enableVideoLayer: 0
137 | useProtectedVideoMemory: 0
138 | minimumSupportedHeadTracking: 0
139 | maximumSupportedHeadTracking: 1
140 | hololens:
141 | depthFormat: 1
142 | depthBufferSharingEnabled: 1
143 | oculus:
144 | sharedDepthBuffer: 1
145 | dashSupport: 1
146 | lowOverheadMode: 0
147 | protectedContext: 0
148 | v2Signing: 0
149 | enable360StereoCapture: 0
150 | protectGraphicsMemory: 0
151 | enableFrameTimingStats: 0
152 | useHDRDisplay: 0
153 | m_ColorGamuts: 00000000
154 | targetPixelDensity: 30
155 | resolutionScalingMode: 0
156 | androidSupportedAspectRatio: 1
157 | androidMaxAspectRatio: 2.1
158 | applicationIdentifier: {}
159 | buildNumber: {}
160 | AndroidBundleVersionCode: 1
161 | AndroidMinSdkVersion: 16
162 | AndroidTargetSdkVersion: 0
163 | AndroidPreferredInstallLocation: 1
164 | aotOptions:
165 | stripEngineCode: 1
166 | iPhoneStrippingLevel: 0
167 | iPhoneScriptCallOptimization: 0
168 | ForceInternetPermission: 0
169 | ForceSDCardPermission: 0
170 | CreateWallpaper: 0
171 | APKExpansionFiles: 0
172 | keepLoadedShadersAlive: 0
173 | StripUnusedMeshComponents: 1
174 | VertexChannelCompressionMask: 4054
175 | iPhoneSdkVersion: 988
176 | iOSTargetOSVersionString: 9.0
177 | tvOSSdkVersion: 0
178 | tvOSRequireExtendedGameController: 0
179 | tvOSTargetOSVersionString: 9.0
180 | uIPrerenderedIcon: 0
181 | uIRequiresPersistentWiFi: 0
182 | uIRequiresFullScreen: 1
183 | uIStatusBarHidden: 1
184 | uIExitOnSuspend: 0
185 | uIStatusBarStyle: 0
186 | iPhoneSplashScreen: {fileID: 0}
187 | iPhoneHighResSplashScreen: {fileID: 0}
188 | iPhoneTallHighResSplashScreen: {fileID: 0}
189 | iPhone47inSplashScreen: {fileID: 0}
190 | iPhone55inPortraitSplashScreen: {fileID: 0}
191 | iPhone55inLandscapeSplashScreen: {fileID: 0}
192 | iPhone58inPortraitSplashScreen: {fileID: 0}
193 | iPhone58inLandscapeSplashScreen: {fileID: 0}
194 | iPadPortraitSplashScreen: {fileID: 0}
195 | iPadHighResPortraitSplashScreen: {fileID: 0}
196 | iPadLandscapeSplashScreen: {fileID: 0}
197 | iPadHighResLandscapeSplashScreen: {fileID: 0}
198 | appleTVSplashScreen: {fileID: 0}
199 | appleTVSplashScreen2x: {fileID: 0}
200 | tvOSSmallIconLayers: []
201 | tvOSSmallIconLayers2x: []
202 | tvOSLargeIconLayers: []
203 | tvOSLargeIconLayers2x: []
204 | tvOSTopShelfImageLayers: []
205 | tvOSTopShelfImageLayers2x: []
206 | tvOSTopShelfImageWideLayers: []
207 | tvOSTopShelfImageWideLayers2x: []
208 | iOSLaunchScreenType: 0
209 | iOSLaunchScreenPortrait: {fileID: 0}
210 | iOSLaunchScreenLandscape: {fileID: 0}
211 | iOSLaunchScreenBackgroundColor:
212 | serializedVersion: 2
213 | rgba: 0
214 | iOSLaunchScreenFillPct: 100
215 | iOSLaunchScreenSize: 100
216 | iOSLaunchScreenCustomXibPath:
217 | iOSLaunchScreeniPadType: 0
218 | iOSLaunchScreeniPadImage: {fileID: 0}
219 | iOSLaunchScreeniPadBackgroundColor:
220 | serializedVersion: 2
221 | rgba: 0
222 | iOSLaunchScreeniPadFillPct: 100
223 | iOSLaunchScreeniPadSize: 100
224 | iOSLaunchScreeniPadCustomXibPath:
225 | iOSUseLaunchScreenStoryboard: 0
226 | iOSLaunchScreenCustomStoryboardPath:
227 | iOSDeviceRequirements: []
228 | iOSURLSchemes: []
229 | iOSBackgroundModes: 0
230 | iOSMetalForceHardShadows: 0
231 | metalEditorSupport: 1
232 | metalAPIValidation: 1
233 | iOSRenderExtraFrameOnPause: 0
234 | appleDeveloperTeamID:
235 | iOSManualSigningProvisioningProfileID:
236 | tvOSManualSigningProvisioningProfileID:
237 | iOSManualSigningProvisioningProfileType: 0
238 | tvOSManualSigningProvisioningProfileType: 0
239 | appleEnableAutomaticSigning: 0
240 | iOSRequireARKit: 0
241 | iOSAutomaticallyDetectAndAddCapabilities: 1
242 | appleEnableProMotion: 0
243 | clonedFromGUID: c0afd0d1d80e3634a9dac47e8a0426ea
244 | templatePackageId: com.unity.template.3d@1.3.0
245 | templateDefaultScene: Assets/Scenes/SampleScene.unity
246 | AndroidTargetArchitectures: 5
247 | AndroidSplashScreenScale: 0
248 | androidSplashScreen: {fileID: 0}
249 | AndroidKeystoreName:
250 | AndroidKeyaliasName:
251 | AndroidBuildApkPerCpuArchitecture: 0
252 | AndroidTVCompatibility: 1
253 | AndroidIsGame: 1
254 | AndroidEnableTango: 0
255 | androidEnableBanner: 1
256 | androidUseLowAccuracyLocation: 0
257 | m_AndroidBanners:
258 | - width: 320
259 | height: 180
260 | banner: {fileID: 0}
261 | androidGamepadSupportLevel: 0
262 | resolutionDialogBanner: {fileID: 0}
263 | m_BuildTargetIcons: []
264 | m_BuildTargetPlatformIcons: []
265 | m_BuildTargetBatching:
266 | - m_BuildTarget: Standalone
267 | m_StaticBatching: 1
268 | m_DynamicBatching: 0
269 | - m_BuildTarget: tvOS
270 | m_StaticBatching: 1
271 | m_DynamicBatching: 0
272 | - m_BuildTarget: Android
273 | m_StaticBatching: 1
274 | m_DynamicBatching: 0
275 | - m_BuildTarget: iPhone
276 | m_StaticBatching: 1
277 | m_DynamicBatching: 0
278 | - m_BuildTarget: WebGL
279 | m_StaticBatching: 0
280 | m_DynamicBatching: 0
281 | m_BuildTargetGraphicsAPIs:
282 | - m_BuildTarget: AndroidPlayer
283 | m_APIs: 0b00000008000000
284 | m_Automatic: 1
285 | - m_BuildTarget: iOSSupport
286 | m_APIs: 10000000
287 | m_Automatic: 1
288 | - m_BuildTarget: AppleTVSupport
289 | m_APIs: 10000000
290 | m_Automatic: 0
291 | - m_BuildTarget: WebGLSupport
292 | m_APIs: 0b000000
293 | m_Automatic: 1
294 | m_BuildTargetVRSettings:
295 | - m_BuildTarget: Standalone
296 | m_Enabled: 0
297 | m_Devices:
298 | - Oculus
299 | - OpenVR
300 | m_BuildTargetEnableVuforiaSettings: []
301 | openGLRequireES31: 0
302 | openGLRequireES31AEP: 0
303 | m_TemplateCustomTags: {}
304 | mobileMTRendering:
305 | Android: 1
306 | iPhone: 1
307 | tvOS: 1
308 | m_BuildTargetGroupLightmapEncodingQuality: []
309 | m_BuildTargetGroupLightmapSettings: []
310 | playModeTestRunnerEnabled: 0
311 | runPlayModeTestAsEditModeTest: 0
312 | actionOnDotNetUnhandledException: 1
313 | enableInternalProfiler: 0
314 | logObjCUncaughtExceptions: 1
315 | enableCrashReportAPI: 0
316 | cameraUsageDescription:
317 | locationUsageDescription:
318 | microphoneUsageDescription:
319 | switchNetLibKey:
320 | switchSocketMemoryPoolSize: 6144
321 | switchSocketAllocatorPoolSize: 128
322 | switchSocketConcurrencyLimit: 14
323 | switchScreenResolutionBehavior: 2
324 | switchUseCPUProfiler: 0
325 | switchApplicationID: 0x01004b9000490000
326 | switchNSODependencies:
327 | switchTitleNames_0:
328 | switchTitleNames_1:
329 | switchTitleNames_2:
330 | switchTitleNames_3:
331 | switchTitleNames_4:
332 | switchTitleNames_5:
333 | switchTitleNames_6:
334 | switchTitleNames_7:
335 | switchTitleNames_8:
336 | switchTitleNames_9:
337 | switchTitleNames_10:
338 | switchTitleNames_11:
339 | switchTitleNames_12:
340 | switchTitleNames_13:
341 | switchTitleNames_14:
342 | switchPublisherNames_0:
343 | switchPublisherNames_1:
344 | switchPublisherNames_2:
345 | switchPublisherNames_3:
346 | switchPublisherNames_4:
347 | switchPublisherNames_5:
348 | switchPublisherNames_6:
349 | switchPublisherNames_7:
350 | switchPublisherNames_8:
351 | switchPublisherNames_9:
352 | switchPublisherNames_10:
353 | switchPublisherNames_11:
354 | switchPublisherNames_12:
355 | switchPublisherNames_13:
356 | switchPublisherNames_14:
357 | switchIcons_0: {fileID: 0}
358 | switchIcons_1: {fileID: 0}
359 | switchIcons_2: {fileID: 0}
360 | switchIcons_3: {fileID: 0}
361 | switchIcons_4: {fileID: 0}
362 | switchIcons_5: {fileID: 0}
363 | switchIcons_6: {fileID: 0}
364 | switchIcons_7: {fileID: 0}
365 | switchIcons_8: {fileID: 0}
366 | switchIcons_9: {fileID: 0}
367 | switchIcons_10: {fileID: 0}
368 | switchIcons_11: {fileID: 0}
369 | switchIcons_12: {fileID: 0}
370 | switchIcons_13: {fileID: 0}
371 | switchIcons_14: {fileID: 0}
372 | switchSmallIcons_0: {fileID: 0}
373 | switchSmallIcons_1: {fileID: 0}
374 | switchSmallIcons_2: {fileID: 0}
375 | switchSmallIcons_3: {fileID: 0}
376 | switchSmallIcons_4: {fileID: 0}
377 | switchSmallIcons_5: {fileID: 0}
378 | switchSmallIcons_6: {fileID: 0}
379 | switchSmallIcons_7: {fileID: 0}
380 | switchSmallIcons_8: {fileID: 0}
381 | switchSmallIcons_9: {fileID: 0}
382 | switchSmallIcons_10: {fileID: 0}
383 | switchSmallIcons_11: {fileID: 0}
384 | switchSmallIcons_12: {fileID: 0}
385 | switchSmallIcons_13: {fileID: 0}
386 | switchSmallIcons_14: {fileID: 0}
387 | switchManualHTML:
388 | switchAccessibleURLs:
389 | switchLegalInformation:
390 | switchMainThreadStackSize: 1048576
391 | switchPresenceGroupId:
392 | switchLogoHandling: 0
393 | switchReleaseVersion: 0
394 | switchDisplayVersion: 1.0.0
395 | switchStartupUserAccount: 0
396 | switchTouchScreenUsage: 0
397 | switchSupportedLanguagesMask: 0
398 | switchLogoType: 0
399 | switchApplicationErrorCodeCategory:
400 | switchUserAccountSaveDataSize: 0
401 | switchUserAccountSaveDataJournalSize: 0
402 | switchApplicationAttribute: 0
403 | switchCardSpecSize: -1
404 | switchCardSpecClock: -1
405 | switchRatingsMask: 0
406 | switchRatingsInt_0: 0
407 | switchRatingsInt_1: 0
408 | switchRatingsInt_2: 0
409 | switchRatingsInt_3: 0
410 | switchRatingsInt_4: 0
411 | switchRatingsInt_5: 0
412 | switchRatingsInt_6: 0
413 | switchRatingsInt_7: 0
414 | switchRatingsInt_8: 0
415 | switchRatingsInt_9: 0
416 | switchRatingsInt_10: 0
417 | switchRatingsInt_11: 0
418 | switchLocalCommunicationIds_0:
419 | switchLocalCommunicationIds_1:
420 | switchLocalCommunicationIds_2:
421 | switchLocalCommunicationIds_3:
422 | switchLocalCommunicationIds_4:
423 | switchLocalCommunicationIds_5:
424 | switchLocalCommunicationIds_6:
425 | switchLocalCommunicationIds_7:
426 | switchParentalControl: 0
427 | switchAllowsScreenshot: 1
428 | switchAllowsVideoCapturing: 1
429 | switchAllowsRuntimeAddOnContentInstall: 0
430 | switchDataLossConfirmation: 0
431 | switchUserAccountLockEnabled: 0
432 | switchSystemResourceMemory: 16777216
433 | switchSupportedNpadStyles: 3
434 | switchNativeFsCacheSize: 32
435 | switchIsHoldTypeHorizontal: 0
436 | switchSupportedNpadCount: 8
437 | switchSocketConfigEnabled: 0
438 | switchTcpInitialSendBufferSize: 32
439 | switchTcpInitialReceiveBufferSize: 64
440 | switchTcpAutoSendBufferSizeMax: 256
441 | switchTcpAutoReceiveBufferSizeMax: 256
442 | switchUdpSendBufferSize: 9
443 | switchUdpReceiveBufferSize: 42
444 | switchSocketBufferEfficiency: 4
445 | switchSocketInitializeEnabled: 1
446 | switchNetworkInterfaceManagerInitializeEnabled: 1
447 | switchPlayerConnectionEnabled: 1
448 | ps4NPAgeRating: 12
449 | ps4NPTitleSecret:
450 | ps4NPTrophyPackPath:
451 | ps4ParentalLevel: 11
452 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000
453 | ps4Category: 0
454 | ps4MasterVersion: 01.00
455 | ps4AppVersion: 01.00
456 | ps4AppType: 0
457 | ps4ParamSfxPath:
458 | ps4VideoOutPixelFormat: 0
459 | ps4VideoOutInitialWidth: 1920
460 | ps4VideoOutBaseModeInitialWidth: 1920
461 | ps4VideoOutReprojectionRate: 60
462 | ps4PronunciationXMLPath:
463 | ps4PronunciationSIGPath:
464 | ps4BackgroundImagePath:
465 | ps4StartupImagePath:
466 | ps4StartupImagesFolder:
467 | ps4IconImagesFolder:
468 | ps4SaveDataImagePath:
469 | ps4SdkOverride:
470 | ps4BGMPath:
471 | ps4ShareFilePath:
472 | ps4ShareOverlayImagePath:
473 | ps4PrivacyGuardImagePath:
474 | ps4NPtitleDatPath:
475 | ps4RemotePlayKeyAssignment: -1
476 | ps4RemotePlayKeyMappingDir:
477 | ps4PlayTogetherPlayerCount: 0
478 | ps4EnterButtonAssignment: 1
479 | ps4ApplicationParam1: 0
480 | ps4ApplicationParam2: 0
481 | ps4ApplicationParam3: 0
482 | ps4ApplicationParam4: 0
483 | ps4DownloadDataSize: 0
484 | ps4GarlicHeapSize: 2048
485 | ps4ProGarlicHeapSize: 2560
486 | ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ
487 | ps4pnSessions: 1
488 | ps4pnPresence: 1
489 | ps4pnFriends: 1
490 | ps4pnGameCustomData: 1
491 | playerPrefsSupport: 0
492 | enableApplicationExit: 0
493 | resetTempFolder: 1
494 | restrictedAudioUsageRights: 0
495 | ps4UseResolutionFallback: 0
496 | ps4ReprojectionSupport: 0
497 | ps4UseAudio3dBackend: 0
498 | ps4SocialScreenEnabled: 0
499 | ps4ScriptOptimizationLevel: 0
500 | ps4Audio3dVirtualSpeakerCount: 14
501 | ps4attribCpuUsage: 0
502 | ps4PatchPkgPath:
503 | ps4PatchLatestPkgPath:
504 | ps4PatchChangeinfoPath:
505 | ps4PatchDayOne: 0
506 | ps4attribUserManagement: 0
507 | ps4attribMoveSupport: 0
508 | ps4attrib3DSupport: 0
509 | ps4attribShareSupport: 0
510 | ps4attribExclusiveVR: 0
511 | ps4disableAutoHideSplash: 0
512 | ps4videoRecordingFeaturesUsed: 0
513 | ps4contentSearchFeaturesUsed: 0
514 | ps4attribEyeToEyeDistanceSettingVR: 0
515 | ps4IncludedModules: []
516 | monoEnv:
517 | splashScreenBackgroundSourceLandscape: {fileID: 0}
518 | splashScreenBackgroundSourcePortrait: {fileID: 0}
519 | spritePackerPolicy:
520 | webGLMemorySize: 256
521 | webGLExceptionSupport: 1
522 | webGLNameFilesAsHashes: 0
523 | webGLDataCaching: 1
524 | webGLDebugSymbols: 0
525 | webGLEmscriptenArgs:
526 | webGLModulesDirectory:
527 | webGLTemplate: APPLICATION:Default
528 | webGLAnalyzeBuildSize: 0
529 | webGLUseEmbeddedResources: 0
530 | webGLCompressionFormat: 1
531 | webGLLinkerTarget: 1
532 | webGLThreadsSupport: 0
533 | scriptingDefineSymbols: {}
534 | platformArchitecture: {}
535 | scriptingBackend: {}
536 | il2cppCompilerConfiguration: {}
537 | managedStrippingLevel: {}
538 | incrementalIl2cppBuild: {}
539 | allowUnsafeCode: 0
540 | additionalIl2CppArgs:
541 | scriptingRuntimeVersion: 1
542 | apiCompatibilityLevelPerPlatform: {}
543 | m_RenderingPath: 1
544 | m_MobileRenderingPath: 1
545 | metroPackageName: Template_3D
546 | metroPackageVersion:
547 | metroCertificatePath:
548 | metroCertificatePassword:
549 | metroCertificateSubject:
550 | metroCertificateIssuer:
551 | metroCertificateNotAfter: 0000000000000000
552 | metroApplicationDescription: Template_3D
553 | wsaImages: {}
554 | metroTileShortName:
555 | metroTileShowName: 0
556 | metroMediumTileShowName: 0
557 | metroLargeTileShowName: 0
558 | metroWideTileShowName: 0
559 | metroSupportStreamingInstall: 0
560 | metroLastRequiredScene: 0
561 | metroDefaultTileSize: 1
562 | metroTileForegroundText: 2
563 | metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0}
564 | metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628,
565 | a: 1}
566 | metroSplashScreenUseBackgroundColor: 0
567 | platformCapabilities: {}
568 | metroTargetDeviceFamilies: {}
569 | metroFTAName:
570 | metroFTAFileTypes: []
571 | metroProtocolName:
572 | metroCompilationOverrides: 1
573 | XboxOneProductId:
574 | XboxOneUpdateKey:
575 | XboxOneSandboxId:
576 | XboxOneContentId:
577 | XboxOneTitleId:
578 | XboxOneSCId:
579 | XboxOneGameOsOverridePath:
580 | XboxOnePackagingOverridePath:
581 | XboxOneAppManifestOverridePath:
582 | XboxOneVersion: 1.0.0.0
583 | XboxOnePackageEncryption: 0
584 | XboxOnePackageUpdateGranularity: 2
585 | XboxOneDescription:
586 | XboxOneLanguage:
587 | - enus
588 | XboxOneCapability: []
589 | XboxOneGameRating: {}
590 | XboxOneIsContentPackage: 0
591 | XboxOneEnableGPUVariability: 1
592 | XboxOneSockets: {}
593 | XboxOneSplashScreen: {fileID: 0}
594 | XboxOneAllowedProductIds: []
595 | XboxOnePersistentLocalStorageSize: 0
596 | XboxOneXTitleMemory: 8
597 | xboxOneScriptCompiler: 1
598 | XboxOneOverrideIdentityName:
599 | vrEditorSettings:
600 | daydream:
601 | daydreamIconForeground: {fileID: 0}
602 | daydreamIconBackground: {fileID: 0}
603 | cloudServicesEnabled:
604 | UNet: 1
605 | luminIcon:
606 | m_Name:
607 | m_ModelFolderPath:
608 | m_PortalFolderPath:
609 | luminCert:
610 | m_CertPath:
611 | m_PrivateKeyPath:
612 | luminIsChannelApp: 0
613 | luminVersion:
614 | m_VersionCode: 1
615 | m_VersionName:
616 | facebookSdkVersion: 7.9.4
617 | facebookAppId:
618 | facebookCookies: 1
619 | facebookLogging: 1
620 | facebookStatus: 1
621 | facebookXfbml: 0
622 | facebookFrictionlessRequests: 1
623 | apiCompatibilityLevel: 6
624 | cloudProjectId:
625 | framebufferDepthMemorylessMode: 0
626 | projectName:
627 | organizationId:
628 | cloudEnabled: 0
629 | enableNativePlatformBackendsForNewInputSystem: 0
630 | disableOldInputManagerSupport: 0
631 | legacyClampBlendShapeWeights: 0
632 |
--------------------------------------------------------------------------------
/Assets/Editor/Xcode/ProjectCapabilityManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace Strings.iOS.Xcode
5 | {
6 | // This class is here to help you add capabilities to your Xcode project.
7 | // Because capabilities modify the PBXProject, the entitlements file and/or the Info.plist and not consistently,
8 | // it can be tedious.
9 | // Therefore this class open the PBXProject that is always modify by capabilities and open Entitlement and info.plist only when needed.
10 | // For optimisation reasons, we write the file only in the close method.
11 | // If you don't call it the file will not be written.
12 | public class ProjectCapabilityManager
13 | {
14 | private readonly string m_BuildPath;
15 | private readonly string m_TargetGuid;
16 | private readonly string m_PBXProjectPath;
17 | private readonly string m_EntitlementFilePath;
18 | private PlistDocument m_Entitlements;
19 | private PlistDocument m_InfoPlist;
20 | protected internal PBXProject project;
21 |
22 | // Create the manager with the required parameter to open files and set the properties in the write place.
23 | public ProjectCapabilityManager(string pbxProjectPath, string entitlementFilePath, string targetName)
24 | {
25 | m_BuildPath = Directory.GetParent(Path.GetDirectoryName(pbxProjectPath)).FullName;
26 |
27 | m_EntitlementFilePath = entitlementFilePath;
28 | m_PBXProjectPath = pbxProjectPath;
29 | project = new PBXProject();
30 | project.ReadFromString(File.ReadAllText(m_PBXProjectPath));
31 | m_TargetGuid = project.TargetGuidByName(targetName);
32 | }
33 |
34 | // Write the actual file to the disk.
35 | // If you don't call this method nothing will change.
36 | public void WriteToFile()
37 | {
38 | File.WriteAllText(m_PBXProjectPath, project.WriteToString());
39 | if (m_Entitlements != null)
40 | m_Entitlements.WriteToFile(PBXPath.Combine(m_BuildPath, m_EntitlementFilePath));
41 | if (m_InfoPlist != null)
42 | m_InfoPlist.WriteToFile(PBXPath.Combine(m_BuildPath, "Info.plist"));
43 | }
44 |
45 | // Add the iCloud capability with the desired options.
46 | public void AddiCloud(bool keyValueStorage, bool iCloudDocument, string[] customContainers)
47 | {
48 | var ent = GetOrCreateEntitlementDoc();
49 | var val = (ent.root[ICloudEntitlements.ContainerIdValue] = new PlistElementArray()) as PlistElementArray;
50 | if (iCloudDocument)
51 | {
52 | val.values.Add(new PlistElementString(ICloudEntitlements.ContainerIdValue));
53 | var ser = (ent.root[ICloudEntitlements.ServicesKey] = new PlistElementArray()) as PlistElementArray;
54 | ser.values.Add(new PlistElementString(ICloudEntitlements.ServicesKitValue));
55 | ser.values.Add(new PlistElementString(ICloudEntitlements.ServicesDocValue));
56 | var ubiquity = (ent.root[ICloudEntitlements.UbiquityContainerIdKey] = new PlistElementArray()) as PlistElementArray;
57 | ubiquity.values.Add(new PlistElementString(ICloudEntitlements.UbiquityContainerIdValue));
58 | for (var i = 0; i < customContainers.Length; i++)
59 | {
60 | ser.values.Add(new PlistElementString(customContainers[i]));
61 | }
62 | }
63 |
64 | if (keyValueStorage)
65 | {
66 | ent.root[ICloudEntitlements.KeyValueStoreKey] = new PlistElementString(ICloudEntitlements.KeyValueStoreValue);
67 | }
68 |
69 | project.AddCapability(m_TargetGuid, PBXCapabilityType.iCloud, m_EntitlementFilePath, iCloudDocument);
70 | }
71 |
72 | // Add Push (or remote) Notifications capability to your project
73 | public void AddPushNotifications(bool development)
74 | {
75 | GetOrCreateEntitlementDoc().root[PushNotificationEntitlements.Key] = new PlistElementString(development ? PushNotificationEntitlements.DevelopmentValue : PushNotificationEntitlements.ProductionValue);
76 | project.AddCapability(m_TargetGuid, PBXCapabilityType.PushNotifications, m_EntitlementFilePath);
77 | }
78 |
79 | // Add GameCenter capability to the project.
80 | public void AddGameCenter()
81 | {
82 | var arr = (GetOrCreateInfoDoc().root[GameCenterInfo.Key] ?? (GetOrCreateInfoDoc().root[GameCenterInfo.Key] = new PlistElementArray())) as PlistElementArray;
83 | arr.values.Add(new PlistElementString(GameCenterInfo.Value));
84 | project.AddCapability(m_TargetGuid, PBXCapabilityType.GameCenter);
85 | }
86 |
87 | // Add Wallet capability to the project.
88 | public void AddWallet(string[] passSubset)
89 | {
90 | var arr = (GetOrCreateEntitlementDoc().root[WalletEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
91 | if ((passSubset == null || passSubset.Length == 0) && arr != null)
92 | {
93 | arr.values.Add(new PlistElementString(WalletEntitlements.BaseValue + WalletEntitlements.BaseValue));
94 | }
95 | else
96 | {
97 | for (var i = 0; i < passSubset.Length; i++)
98 | {
99 | if (arr != null)
100 | arr.values.Add(new PlistElementString(WalletEntitlements.BaseValue + passSubset[i]));
101 | }
102 | }
103 |
104 | project.AddCapability(m_TargetGuid, PBXCapabilityType.Wallet, m_EntitlementFilePath);
105 | }
106 |
107 | // Add Siri capability to the project.
108 | public void AddSiri()
109 | {
110 | GetOrCreateEntitlementDoc().root[SiriEntitlements.Key] = new PlistElementBoolean(true);
111 |
112 | project.AddCapability(m_TargetGuid, PBXCapabilityType.Siri, m_EntitlementFilePath);
113 | }
114 |
115 | // Add Apple Pay capability to the project.
116 | public void AddApplePay(string[] merchants)
117 | {
118 | var arr = (GetOrCreateEntitlementDoc().root[ApplePayEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
119 | for (var i = 0; i < merchants.Length; i++)
120 | {
121 | arr.values.Add(new PlistElementString(merchants[i]));
122 | }
123 |
124 | project.AddCapability(m_TargetGuid, PBXCapabilityType.ApplePay, m_EntitlementFilePath);
125 | }
126 |
127 | // Add In App Purchase capability to the project.
128 | public void AddInAppPurchase()
129 | {
130 | project.AddCapability(m_TargetGuid, PBXCapabilityType.InAppPurchase);
131 | }
132 |
133 | // Add Maps capability to the project.
134 | public void AddMaps(MapsOptions options)
135 | {
136 | var bundleArr = (GetOrCreateInfoDoc().root[MapsInfo.BundleKey] ?? (GetOrCreateInfoDoc().root[MapsInfo.BundleKey] = new PlistElementArray())) as PlistElementArray;
137 | bundleArr.values.Add(new PlistElementDict());
138 | PlistElementDict bundleDic = GetOrCreateUniqueDictElementInArray(bundleArr);
139 | bundleDic[MapsInfo.BundleNameKey] = new PlistElementString(MapsInfo.BundleNameValue);
140 | var bundleTypeArr = (bundleDic[MapsInfo.BundleTypeKey] ?? (bundleDic[MapsInfo.BundleTypeKey] = new PlistElementArray())) as PlistElementArray;
141 | GetOrCreateStringElementInArray(bundleTypeArr, MapsInfo.BundleTypeValue);
142 |
143 | var optionArr = (GetOrCreateInfoDoc().root[MapsInfo.ModeKey] ??
144 | (GetOrCreateInfoDoc().root[MapsInfo.ModeKey] = new PlistElementArray())) as PlistElementArray;
145 | if ((options & MapsOptions.Airplane) == MapsOptions.Airplane)
146 | {
147 | GetOrCreateStringElementInArray(optionArr, MapsInfo.ModePlaneValue);
148 | }
149 | if ((options & MapsOptions.Bike) == MapsOptions.Bike)
150 | {
151 | GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeBikeValue);
152 | }
153 | if ((options & MapsOptions.Bus) == MapsOptions.Bus)
154 | {
155 | GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeBusValue);
156 | }
157 | if ((options & MapsOptions.Car) == MapsOptions.Car)
158 | {
159 | GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeCarValue);
160 | }
161 | if ((options & MapsOptions.Ferry) == MapsOptions.Ferry)
162 | {
163 | GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeFerryValue);
164 | }
165 | if ((options & MapsOptions.Other) == MapsOptions.Other)
166 | {
167 | GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeOtherValue);
168 | }
169 | if ((options & MapsOptions.Pedestrian) == MapsOptions.Pedestrian)
170 | {
171 | GetOrCreateStringElementInArray(optionArr, MapsInfo.ModePedestrianValue);
172 | }
173 | if ((options & MapsOptions.RideSharing) == MapsOptions.RideSharing)
174 | {
175 | GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeRideShareValue);
176 | }
177 | if ((options & MapsOptions.StreetCar) == MapsOptions.StreetCar)
178 | {
179 | GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeStreetCarValue);
180 | }
181 | if ((options & MapsOptions.Subway) == MapsOptions.Subway)
182 | {
183 | GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeSubwayValue);
184 | }
185 | if ((options & MapsOptions.Taxi) == MapsOptions.Taxi)
186 | {
187 | GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeTaxiValue);
188 | }
189 | if ((options & MapsOptions.Train) == MapsOptions.Train)
190 | {
191 | GetOrCreateStringElementInArray(optionArr, MapsInfo.ModeTrainValue);
192 | }
193 |
194 | project.AddCapability(m_TargetGuid, PBXCapabilityType.Maps);
195 | }
196 |
197 | // Add Personal VPN capability to the project.
198 | public void AddPersonalVPN()
199 | {
200 | var arr = (GetOrCreateEntitlementDoc().root[VPNEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
201 | arr.values.Add(new PlistElementString(VPNEntitlements.Value));
202 |
203 | project.AddCapability(m_TargetGuid, PBXCapabilityType.PersonalVPN, m_EntitlementFilePath);
204 | }
205 |
206 | // Add Background capability to the project with the options wanted.
207 | public void AddBackgroundModes(BackgroundModesOptions options)
208 | {
209 | var optionArr = (GetOrCreateInfoDoc().root[BackgroundInfo.Key] ??
210 | (GetOrCreateInfoDoc().root[BackgroundInfo.Key] = new PlistElementArray())) as PlistElementArray;
211 |
212 | if ((options & BackgroundModesOptions.ActsAsABluetoothLEAccessory) == BackgroundModesOptions.ActsAsABluetoothLEAccessory)
213 | {
214 | GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeActsBluetoothValue);
215 | }
216 | if ((options & BackgroundModesOptions.AudioAirplayPiP) == BackgroundModesOptions.AudioAirplayPiP)
217 | {
218 | GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeAudioValue);
219 | }
220 | if ((options & BackgroundModesOptions.BackgroundFetch) == BackgroundModesOptions.BackgroundFetch)
221 | {
222 | GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeFetchValue);
223 | }
224 | if ((options & BackgroundModesOptions.ExternalAccessoryCommunication) == BackgroundModesOptions.ExternalAccessoryCommunication)
225 | {
226 | GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeExtAccessoryValue);
227 | }
228 | if ((options & BackgroundModesOptions.LocationUpdates) == BackgroundModesOptions.LocationUpdates)
229 | {
230 | GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeLocationValue);
231 | }
232 | if ((options & BackgroundModesOptions.NewsstandDownloads) == BackgroundModesOptions.NewsstandDownloads)
233 | {
234 | GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeNewsstandValue);
235 | }
236 | if ((options & BackgroundModesOptions.RemoteNotifications) == BackgroundModesOptions.RemoteNotifications)
237 | {
238 | GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModePushValue);
239 | }
240 | if ((options & BackgroundModesOptions.VoiceOverIP) == BackgroundModesOptions.VoiceOverIP)
241 | {
242 | GetOrCreateStringElementInArray(optionArr, BackgroundInfo.ModeVOIPValue);
243 | }
244 | project.AddCapability(m_TargetGuid, PBXCapabilityType.BackgroundModes);
245 | }
246 |
247 | // Add Keychain Sharing capability to the project with a list of groups.
248 | public void AddKeychainSharing(string[] accessGroups)
249 | {
250 | var arr = (GetOrCreateEntitlementDoc().root[KeyChainEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
251 | if (accessGroups != null)
252 | {
253 | for (var i = 0; i < accessGroups.Length; i++)
254 | {
255 | arr.values.Add(new PlistElementString(accessGroups[i]));
256 | }
257 | }
258 | else
259 | {
260 | arr.values.Add(new PlistElementString(KeyChainEntitlements.DefaultValue));
261 | }
262 |
263 | project.AddCapability(m_TargetGuid, PBXCapabilityType.KeychainSharing, m_EntitlementFilePath);
264 | }
265 |
266 | // Add Inter App Audio capability to the project.
267 | public void AddInterAppAudio()
268 | {
269 | GetOrCreateEntitlementDoc().root[AudioEntitlements.Key] = new PlistElementBoolean(true);
270 | project.AddCapability(m_TargetGuid, PBXCapabilityType.InterAppAudio, m_EntitlementFilePath);
271 | }
272 |
273 | // Add Associated Domains capability to the project.
274 | public void AddAssociatedDomains(string[] domains)
275 | {
276 | var arr = (GetOrCreateEntitlementDoc().root[AssociatedDomainsEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
277 | for (var i = 0; i < domains.Length; i++)
278 | {
279 | arr.values.Add(new PlistElementString(domains[i]));
280 | }
281 |
282 | project.AddCapability(m_TargetGuid, PBXCapabilityType.AssociatedDomains, m_EntitlementFilePath);
283 | }
284 |
285 | // Add App Groups capability to the project.
286 | public void AddAppGroups(string[] groups)
287 | {
288 | var arr = (GetOrCreateEntitlementDoc().root[AppGroupsEntitlements.Key] = new PlistElementArray()) as PlistElementArray;
289 | for (var i = 0; i < groups.Length; i++)
290 | {
291 | arr.values.Add(new PlistElementString(groups[i]));
292 | }
293 |
294 | project.AddCapability(m_TargetGuid, PBXCapabilityType.AppGroups, m_EntitlementFilePath);
295 | }
296 |
297 | // Add HomeKit capability to the project.
298 | public void AddHomeKit()
299 | {
300 | GetOrCreateEntitlementDoc().root[HomeKitEntitlements.Key] = new PlistElementBoolean(true);
301 | project.AddCapability(m_TargetGuid, PBXCapabilityType.HomeKit, m_EntitlementFilePath);
302 | }
303 |
304 | // Add Data Protection capability to the project.
305 | public void AddDataProtection()
306 | {
307 | GetOrCreateEntitlementDoc().root[DataProtectionEntitlements.Key] = new PlistElementString(DataProtectionEntitlements.Value);
308 | project.AddCapability(m_TargetGuid, PBXCapabilityType.DataProtection, m_EntitlementFilePath);
309 | }
310 |
311 | // Add HealthKit capability to the project.
312 | public void AddHealthKit()
313 | {
314 | var capabilityArr = (GetOrCreateInfoDoc().root[HealthInfo.Key] ??
315 | (GetOrCreateInfoDoc().root[HealthInfo.Key] = new PlistElementArray())) as PlistElementArray;
316 | GetOrCreateStringElementInArray(capabilityArr, HealthInfo.Value);
317 | GetOrCreateEntitlementDoc().root[HealthKitEntitlements.Key] = new PlistElementBoolean(true);
318 | project.AddCapability(m_TargetGuid, PBXCapabilityType.HealthKit, m_EntitlementFilePath);
319 | }
320 |
321 | // Add Wireless Accessory Configuration capability to the project.
322 | public void AddWirelessAccessoryConfiguration()
323 | {
324 | GetOrCreateEntitlementDoc().root[WirelessAccessoryConfigurationEntitlements.Key] = new PlistElementBoolean(true);
325 | project.AddCapability(m_TargetGuid, PBXCapabilityType.WirelessAccessoryConfiguration, m_EntitlementFilePath);
326 | }
327 |
328 | private PlistDocument GetOrCreateEntitlementDoc()
329 | {
330 | if (m_Entitlements == null)
331 | {
332 | m_Entitlements = new PlistDocument();
333 | string[] entitlementsFiles = Directory.GetFiles(m_BuildPath, m_EntitlementFilePath);
334 | if (entitlementsFiles.Length > 0)
335 | {
336 | m_Entitlements.ReadFromFile(entitlementsFiles[0]);
337 | }
338 | else
339 | {
340 | m_Entitlements.Create();
341 | }
342 | }
343 |
344 | return m_Entitlements;
345 | }
346 |
347 | private PlistDocument GetOrCreateInfoDoc()
348 | {
349 | if (m_InfoPlist == null)
350 | {
351 | m_InfoPlist = new PlistDocument();
352 | string[] infoFiles = Directory.GetFiles(m_BuildPath + "/", "Info.plist");
353 | if (infoFiles.Length > 0)
354 | {
355 | m_InfoPlist.ReadFromFile(infoFiles[0]);
356 | }
357 | else
358 | {
359 | m_InfoPlist.Create();
360 | }
361 | }
362 |
363 | return m_InfoPlist;
364 | }
365 |
366 | private PlistElementString GetOrCreateStringElementInArray(PlistElementArray root, string value)
367 | {
368 | PlistElementString r = null;
369 | var c = root.values.Count;
370 | var exist = false;
371 | for (var i = 0; i < c; i++)
372 | {
373 | if (root.values[i] is PlistElementString && (root.values[i] as PlistElementString).value == value)
374 | {
375 | r = root.values[i] as PlistElementString;
376 | exist = true;
377 | }
378 | }
379 | if (!exist)
380 | {
381 | r = new PlistElementString(value);
382 | root.values.Add(r);
383 | }
384 | return r;
385 | }
386 |
387 | private PlistElementDict GetOrCreateUniqueDictElementInArray(PlistElementArray root)
388 | {
389 | PlistElementDict r;
390 | if (root.values.Count == 0)
391 | {
392 | r = root.values[0] as PlistElementDict;
393 | }
394 | else
395 | {
396 | r = new PlistElementDict();
397 | root.values.Add(r);
398 | }
399 | return r;
400 | }
401 | }
402 |
403 | // The list of options available for Background Mode.
404 | [Flags]
405 | [Serializable]
406 | public enum BackgroundModesOptions
407 | {
408 | None = 0,
409 | AudioAirplayPiP = 1<<0,
410 | LocationUpdates = 1<<1,
411 | VoiceOverIP = 1<<2,
412 | NewsstandDownloads = 1<<3,
413 | ExternalAccessoryCommunication = 1<<4,
414 | UsesBluetoothLEAccessory = 1<<5,
415 | ActsAsABluetoothLEAccessory = 1<<6,
416 | BackgroundFetch = 1<<7,
417 | RemoteNotifications = 1<<8
418 | }
419 |
420 | // The list of options available for Maps.
421 | [Serializable]
422 | [Flags]
423 | public enum MapsOptions
424 | {
425 | None = 0,
426 | Airplane = 1<<0,
427 | Bike = 1<<1,
428 | Bus = 1<<2,
429 | Car = 1<<3,
430 | Ferry = 1<<4,
431 | Pedestrian = 1<<5,
432 | RideSharing = 1<<6,
433 | StreetCar = 1<<7,
434 | Subway = 1<<8,
435 | Taxi = 1<<9,
436 | Train = 1<<10,
437 | Other = 1<<11
438 | }
439 |
440 | /* Follows the large quantity of string used as key and value all over the place in the info.plist or entitlements file. */
441 | internal class GameCenterInfo
442 | {
443 | internal static readonly string Key = "UIRequiredDeviceCapabilities";
444 | internal static readonly string Value = "gamekit";
445 | }
446 |
447 | internal class MapsInfo
448 | {
449 | internal static readonly string BundleKey = "CFBundleDocumentTypes";
450 | internal static readonly string BundleNameKey = "CFBundleTypeName";
451 | internal static readonly string BundleNameValue = "MKDirectionsRequest";
452 | internal static readonly string BundleTypeKey = "LSItemContentTypes";
453 | internal static readonly string BundleTypeValue = "com.apple.maps.directionsrequest";
454 | internal static readonly string ModeKey = "MKDirectionsApplicationSupportedModes";
455 | internal static readonly string ModePlaneValue = "MKDirectionsModePlane";
456 | internal static readonly string ModeBikeValue = "MKDirectionsModeBike";
457 | internal static readonly string ModeBusValue = "MKDirectionsModeBus";
458 | internal static readonly string ModeCarValue = "MKDirectionsModeCar";
459 | internal static readonly string ModeFerryValue = "MKDirectionsModeFerry";
460 | internal static readonly string ModeOtherValue = "MKDirectionsModeOther";
461 | internal static readonly string ModePedestrianValue = "MKDirectionsModePedestrian";
462 | internal static readonly string ModeRideShareValue = "MKDirectionsModeRideShare";
463 | internal static readonly string ModeStreetCarValue = "MKDirectionsModeStreetCar";
464 | internal static readonly string ModeSubwayValue = "MKDirectionsModeSubway";
465 | internal static readonly string ModeTaxiValue = "MKDirectionsModeTaxi";
466 | internal static readonly string ModeTrainValue = "MKDirectionsModeTrain";
467 | }
468 |
469 | internal class BackgroundInfo
470 | {
471 | internal static readonly string Key = "UIBackgroundModes";
472 | internal static readonly string ModeAudioValue = "audio";
473 | internal static readonly string ModeBluetoothValue = "bluetooth-central";
474 | internal static readonly string ModeActsBluetoothValue = "bluetooth-peripheral";
475 | internal static readonly string ModeExtAccessoryValue = "external-accessory";
476 | internal static readonly string ModeFetchValue = "fetch";
477 | internal static readonly string ModeLocationValue = "location";
478 | internal static readonly string ModeNewsstandValue = "newsstand-content";
479 | internal static readonly string ModePushValue = "remote-notification";
480 | internal static readonly string ModeVOIPValue = "voip";
481 | }
482 |
483 | internal class HealthInfo
484 | {
485 | internal static readonly string Key = "UIRequiredDeviceCapabilities";
486 | internal static readonly string Value = "healthkit";
487 | }
488 |
489 | internal class ICloudEntitlements
490 | {
491 | internal static readonly string ContainerIdKey = "com.apple.developer.icloud-container-identifiers";
492 | internal static readonly string UbiquityContainerIdKey = "com.apple.developer.ubiquity-container-identifiers";
493 | internal static readonly string ContainerIdValue = "iCloud.$(CFBundleIdentifier)";
494 | internal static readonly string UbiquityContainerIdValue = "iCloud.$(CFBundleIdentifier)";
495 | internal static readonly string ServicesKey = "com.apple.developer.icloud-services";
496 | internal static readonly string ServicesDocValue = "CloudDocuments";
497 | internal static readonly string ServicesKitValue = "CloudKit";
498 | internal static readonly string KeyValueStoreKey = "com.apple.developer.ubiquity-kvstore-identifier";
499 | internal static readonly string KeyValueStoreValue = "$(TeamIdentifierPrefix)$(CFBundleIdentifier)";
500 | }
501 |
502 | internal class PushNotificationEntitlements
503 | {
504 | internal static readonly string Key = "aps-environment";
505 | internal static readonly string DevelopmentValue = "development";
506 | internal static readonly string ProductionValue = "production";
507 | }
508 |
509 | internal class WalletEntitlements
510 | {
511 | internal static readonly string Key = "com.apple.developer.pass-type-identifiers";
512 | internal static readonly string BaseValue = "$(TeamIdentifierPrefix)";
513 | internal static readonly string DefaultValue = "*";
514 | }
515 |
516 | internal class SiriEntitlements
517 | {
518 | internal static readonly string Key = "com.apple.developer.siri";
519 | }
520 |
521 | internal class ApplePayEntitlements
522 | {
523 | internal static readonly string Key = "com.apple.developer.in-app-payments";
524 | }
525 |
526 | internal class VPNEntitlements
527 | {
528 | internal static readonly string Key = "com.apple.developer.networking.vpn.api";
529 | internal static readonly string Value = "allow-vpn";
530 | }
531 |
532 | internal class KeyChainEntitlements
533 | {
534 | internal static readonly string Key = "keychain-access-groups";
535 | internal static readonly string DefaultValue = "$(AppIdentifierPrefix)$(CFBundleIdentifier)";
536 | }
537 |
538 | internal class AudioEntitlements
539 | {
540 | internal static readonly string Key = "inter-app-audio";
541 | }
542 |
543 | internal class AssociatedDomainsEntitlements
544 | {
545 | // value is an array of string of domains
546 | internal static readonly string Key = "com.apple.developer.associated-domains";
547 | }
548 |
549 | internal class AppGroupsEntitlements
550 | {
551 | // value is an array of string of groups
552 | internal static readonly string Key = "com.apple.security.application-groups";
553 | }
554 |
555 | internal class HomeKitEntitlements
556 | {
557 | // value is bool true.
558 | internal static readonly string Key = "com.apple.developer.homekit";
559 | }
560 |
561 | internal class DataProtectionEntitlements
562 | {
563 | internal static readonly string Key = "com.apple.developer.default-data-protection";
564 | internal static readonly string Value = "NSFileProtectionComplete";
565 | }
566 |
567 | internal class HealthKitEntitlements
568 | {
569 | // value is bool true.
570 | internal static readonly string Key = "com.apple.developer.healthkit";
571 | }
572 |
573 | internal class WirelessAccessoryConfigurationEntitlements
574 | {
575 | // value is bool true.
576 | internal static readonly string Key = "com.apple.external-accessory.wireless-configuration";
577 | }
578 | }
579 |
--------------------------------------------------------------------------------