private static NativeFilePickerCustomTypes GetInstance(bool createIfNotExists)
        {
            NativeFilePickerCustomTypes instance = null;

            string[] instances = AssetDatabase.FindAssets("t:NativeFilePickerCustomTypes");
            if (instances != null && instances.Length > 0)
            {
                instance = AssetDatabase.LoadAssetAtPath <NativeFilePickerCustomTypes>(AssetDatabase.GUIDToAssetPath(instances[0]));
            }

            if (!instance && createIfNotExists)
            {
                Directory.CreateDirectory(Path.GetDirectoryName(INITIAL_SAVE_PATH));

                AssetDatabase.CreateAsset(CreateInstance <NativeFilePickerCustomTypes>(), INITIAL_SAVE_PATH);
                AssetDatabase.SaveAssets();
                instance = AssetDatabase.LoadAssetAtPath <NativeFilePickerCustomTypes>(INITIAL_SAVE_PATH);

                Debug.Log("Created NativeFilePickerCustomTypes file at " + INITIAL_SAVE_PATH + ". You can move this file around freely.", instance);
            }

            return(instance);
        }
        public static void OnPostprocessBuild(BuildTarget target, string buildPath)
        {
            // Add declared custom types to Info.plist
            if (target == BuildTarget.iOS)
            {
                NativeFilePickerCustomTypes.TypeHolder[] customTypes = NativeFilePickerCustomTypes.GetCustomTypes();
                if (customTypes != null)
                {
                    string plistPath = Path.Combine(buildPath, "Info.plist");

                    PlistDocument plist = new PlistDocument();
                    plist.ReadFromString(File.ReadAllText(plistPath));

                    PlistElementDict rootDict = plist.root;

                    for (int i = 0; i < customTypes.Length; i++)
                    {
                        NativeFilePickerCustomTypes.TypeHolder customType = customTypes[i];
                        PlistElementArray customTypesArray = GetCustomTypesArray(rootDict, customType.isExported);

                        // Don't allow duplicate entries
                        RemoveCustomTypeIfExists(customTypesArray, customType.identifier);

                        PlistElementDict customTypeDict = customTypesArray.AddDict();
                        customTypeDict.SetString("UTTypeIdentifier", customType.identifier);
                        customTypeDict.SetString("UTTypeDescription", customType.description);

                        PlistElementArray conformsTo = customTypeDict.CreateArray("UTTypeConformsTo");
                        for (int j = 0; j < customType.conformsTo.Length; j++)
                        {
                            conformsTo.AddString(customType.conformsTo[j]);
                        }

                        PlistElementDict  tagSpecification = customTypeDict.CreateDict("UTTypeTagSpecification");
                        PlistElementArray tagExtensions    = tagSpecification.CreateArray("public.filename-extension");
                        for (int j = 0; j < customType.extensions.Length; j++)
                        {
                            tagExtensions.AddString(customType.extensions[j]);
                        }
                    }

                    File.WriteAllText(plistPath, plist.WriteToString());
                }
            }

            // Rest of the function shouldn't execute unless build post-processing is enabled
            if (!AUTO_SETUP_FRAMEWORKS && !AUTO_SETUP_ICLOUD)
            {
                return;
            }

            if (target == BuildTarget.iOS)
            {
                string pbxProjectPath = PBXProject.GetPBXProjectPath(buildPath);

                PBXProject pbxProject = new PBXProject();
                pbxProject.ReadFromFile(pbxProjectPath);

#if UNITY_2019_3_OR_NEWER
                string targetGUID = pbxProject.GetUnityFrameworkTargetGuid();
#else
                string targetGUID = pbxProject.TargetGuidByName(PBXProject.GetUnityTargetName());
#endif

                if (AUTO_SETUP_FRAMEWORKS)
                {
                    pbxProject.AddBuildProperty(targetGUID, "OTHER_LDFLAGS", "-framework MobileCoreServices");
                    pbxProject.AddBuildProperty(targetGUID, "OTHER_LDFLAGS", "-framework CloudKit");
                }

#if !UNITY_2017_1_OR_NEWER
                if (AUTO_SETUP_ICLOUD)
                {
                    // Add iCloud capability without Cloud Build support on 5.6 or earlier
                    string entitlementsPath = Path.Combine(buildPath, "iCloud.entitlements");
                    File.WriteAllText(entitlementsPath, ICLOUD_ENTITLEMENTS);
                    pbxProject.AddFile(entitlementsPath, Path.GetFileName(entitlementsPath));
                    pbxProject.AddBuildProperty(targetGUID, "CODE_SIGN_ENTITLEMENTS", entitlementsPath);
                }
#endif

                File.WriteAllText(pbxProjectPath, pbxProject.WriteToString());

#if UNITY_2017_1_OR_NEWER
                if (AUTO_SETUP_ICLOUD)
                {
                    // Add iCloud capability with Cloud Build support on 2017.1+
#if UNITY_2019_3_OR_NEWER
                    ProjectCapabilityManager manager = new ProjectCapabilityManager(pbxProjectPath, "iCloud.entitlements", "Unity-iPhone");
#else
                    ProjectCapabilityManager manager = new ProjectCapabilityManager(pbxProjectPath, "iCloud.entitlements", PBXProject.GetUnityTargetName());
#endif
#if UNITY_2018_3_OR_NEWER
                    manager.AddiCloud(false, true, false, true, null);
#else
                    manager.AddiCloud(false, true, true, null);
#endif
                    manager.WriteToFile();
                }
#endif
            }
        }
        public static TypeHolder[] GetCustomTypes()
        {
            NativeFilePickerCustomTypes instance = GetInstance(false);

            return(instance ? instance.customTypes : null);
        }