Ejemplo n.º 1
0
        private static void UpdateIOSPlist(string path)
        {
#if UNITY_IOS
            string plistPath = Path.Combine(path, "Info.plist");

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


            //Get Root
            PlistElementDict rootDict = plist.root;


            PlistElementString calendarPrivacy = (PlistElementString)rootDict["NSCalendarsUsageDescription"];
            if (calendarPrivacy == null)
            {
                rootDict.SetString("NSCalendarsUsageDescription", "Some ad content may create a calendar event.");
            }

            PlistElementString photoPrivacy = (PlistElementString)rootDict["NSPhotoLibraryUsageDescription"];
            if (photoPrivacy == null)
            {
                rootDict.SetString("NSPhotoLibraryUsageDescription", "Some ad content may require access to the photo library.");
            }

            PlistElementString cameraPrivacy = (PlistElementString)rootDict["NSCameraUsageDescription"];
            if (cameraPrivacy == null)
            {
                rootDict.SetString("NSCameraUsageDescription", "Some ad content may access camera to take picture.");
            }

            PlistElementString motionPrivacy = (PlistElementString)rootDict["NSMotionUsageDescription"];
            if (motionPrivacy == null)
            {
                rootDict.SetString("NSMotionUsageDescription", "Some ad content may require access to accelerometer for interactive ad experience.");
            }

            File.WriteAllText(plistPath, plist.WriteToString());
#endif
        }
        private static void RemoveCustomTypeIfExists(PlistElementArray customTypesArray, string UTI)
        {
            List <PlistElement> values = customTypesArray.values;

            if (values == null)
            {
                return;
            }

            for (int i = values.Count - 1; i >= 0; i--)
            {
                PlistElementDict exportedType = values[i] as PlistElementDict;
                if (exportedType != null)
                {
                    PlistElementString exportedTypeID = exportedType["UTTypeIdentifier"] as PlistElementString;
                    if (exportedTypeID != null && exportedTypeID.value == UTI)
                    {
                        values.RemoveAt(i);
                    }
                }
            }
        }
Ejemplo n.º 3
0
    public static void OnPostProcessBuild(BuildTarget buildTarget, string path)
    {
        if (buildTarget == BuildTarget.iOS)
        {
            #if UNITY_IOS
            //Modify PList File and add AdMob ID
            string        plistPath = path + "/Info.plist";
            PlistDocument plist     = new PlistDocument();
            plist.ReadFromString(File.ReadAllText(plistPath));

            PlistElementDict rootDict = plist.root;

            string buildKey = "CFBundleVersion";
            rootDict.SetString(buildKey, "1");

            rootDict["GADApplicationIdentifier"] = new PlistElementString("ca-app-pub-8277769580123099~4622099382");

            PlistElementDict nsAppTransportSecurityDict = rootDict["NSAppTransportSecurity"].AsDict();
            nsAppTransportSecurityDict["NSAllowsArbitraryLoads"] = new PlistElementBoolean(true);

            rootDict["NSAppTransportSecurity"] = nsAppTransportSecurityDict;

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


            //Add AdSupport.framework
            string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj";

            PBXProject proj = new PBXProject();
            proj.ReadFromString(File.ReadAllText(projPath));

            string target = proj.GetUnityMainTargetGuid();

            proj.AddFrameworkToProject(target, "AdSupport.framework", true);

            File.WriteAllText(projPath, proj.WriteToString());
            #endif
        }
    }
Ejemplo n.º 4
0
    public void OnPostprocessBuild(BuildTarget target, string path)
    {
        // iOS and OSX share same info.plist entries to support Custom URI Schemes
        if (target == BuildTarget.StandaloneOSX || target == BuildTarget.iOS)
        {
            Debug.Log("InfoPlistPostProcessBuild.OnPostprocessBuild for target " + target + " at path " + path);
            var plistPath = string.Empty;
            if (target == BuildTarget.StandaloneOSX)
            {
                plistPath = $"{path}/Contents/Info.plist";
            }
            if (target == BuildTarget.iOS)
            {
                plistPath = $"{path}/Info.plist";
            }

            if (File.Exists(plistPath))
            {
                var plistDocument = new PlistDocument();
                plistDocument.ReadFromFile(plistPath);
                var rootDict = plistDocument.root;
                if (!rootDict.values.ContainsKey("CFBundleURLTypes"))
                {
                    // Create Custom URI Scheme entry
                    var urlTypeArray  = new PlistElementArray();
                    var urlDict       = urlTypeArray.AddDict();
                    var urlBundleName = new PlistElementString("Unity Reflect");
                    urlDict.values.Add("CFBundleURLName", urlBundleName);
                    var urlBundleSchemes = new PlistElementArray();
                    urlBundleSchemes.AddString("reflect");
                    urlDict.values.Add("CFBundleURLSchemes", urlBundleSchemes);
                    rootDict.values.Add("CFBundleURLTypes", urlTypeArray);

                    // Write back our changes to Info.plist
                    File.WriteAllText(plistPath, plistDocument.WriteToString());
                }
            }
        }
    }
        private static void AddPlistVariables(string projectPath)
        {
            var infoPlist     = new PlistDocument();
            var infoPlistPath = projectPath + "/Info.plist";

            infoPlist.ReadFromFile(infoPlistPath);

            foreach (var variable in ISD_Settings.Instance.PlistVariables)
            {
                PlistElement plistVariable = null;
                switch (variable.Type)
                {
                case ISD_PlistKeyType.String:
                    plistVariable = new PlistElementString(variable.StringValue);
                    break;

                case ISD_PlistKeyType.Integer:
                    plistVariable = new PlistElementInteger(variable.IntegerValue);
                    break;

                case ISD_PlistKeyType.Boolean:
                    plistVariable = new PlistElementBoolean(variable.BooleanValue);
                    break;

                case ISD_PlistKeyType.Array:
                    plistVariable = CreatePlistArray(variable);
                    break;

                case ISD_PlistKeyType.Dictionary:
                    plistVariable = CreatePlistDict(variable);
                    break;
                }

                infoPlist.root[variable.Name] = plistVariable;
            }

            infoPlist.WriteToFile(infoPlistPath);
        }
Ejemplo n.º 6
0
        private static void UpdateIOSPlist(string path, Yodo1AdSettings settings)
        {
            string        plistPath = Path.Combine(path, "Info.plist");
            PlistDocument plist     = new PlistDocument();

            plist.ReadFromString(File.ReadAllText(plistPath));

            //Get Root
            PlistElementDict rootDict          = plist.root;
            PlistElementDict transportSecurity = rootDict.CreateDict("NSAppTransportSecurity");

            transportSecurity.SetBoolean("NSAllowsArbitraryLoads", true);

            //Set AppLovinSdkKey
            rootDict.SetString("AppLovinSdkKey", Yodo1EditorConstants.DEFAULT_APPLOVIN_SDK_KEY);

            //Set AdMob APP Id
            if (settings.iOSSettings.GlobalRegion)
            {
                rootDict.SetString("GADApplicationIdentifier", settings.iOSSettings.AdmobAppID);
            }

            PlistElementString privacy = (PlistElementString)rootDict["NSLocationAlwaysUsageDescription"];

            if (privacy == null)
            {
                rootDict.SetString("NSLocationAlwaysUsageDescription", "Some ad content may require access to the location for an interactive ad experience.");
            }

            PlistElementString privacy1 = (PlistElementString)rootDict["NSLocationWhenInUseUsageDescription"];

            if (privacy1 == null)
            {
                rootDict.SetString("NSLocationWhenInUseUsageDescription", "Some ad content may require access to the location for an interactive ad experience.");
            }

            File.WriteAllText(plistPath, plist.WriteToString());
        }
Ejemplo n.º 7
0
    public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
    {
        Debug.Log("BuildTarget " + target);
        Debug.Log(pathToBuiltProject);
        if (target == BuildTarget.iOS)
        {
            string plistPath = pathToBuiltProject + "/Info.plist";
#if UNITY_IOS
            Debug.Log("add photo write permission");
            PlistDocument plist = new PlistDocument();
            plist.ReadFromFile(plistPath);

            PlistElementDict root = plist.root;

            const string photoWritePermissionKey   = "NSPhotoLibraryAddUsageDescription";
            const string photoWritePermissionValue = "for snap shot";

            PlistElementString e = new PlistElementString(photoWritePermissionValue);
            root[photoWritePermissionKey] = e;

            plist.WriteToFile(plistPath);
#endif
        }
    }
Ejemplo n.º 8
0
        private static void RunPostProcessTasksIos(string projectPath)
        {
//#if UNITY_IOS
            Debug.Log("[PostProcessBuild] Starting to perform post build tasks for iOS platform.");

            string xcodeProjectPath = projectPath + "/Unity-iPhone.xcodeproj/project.pbxproj";

            PBXProject xcodeProject = new PBXProject();

            xcodeProject.ReadFromFile(xcodeProjectPath);

            string xcodeTarget = xcodeProject.TargetGuidByName("Unity-iPhone");

            // 1.
            // We need frameworks to be added to the project:
            // - libxml2.tbd

            //Debug.Log("[PostProcessBuild] Adding libxml2 to Xcode project.");
            //xcodeProject.AddFrameworkToProject(xcodeTarget, "libxml2.tbd", true);
            //Debug.Log("[PostProcessBuild] libxml2 added successfully.");


            // 2.
            // The adjust SDK needs to have -lxml2 flag set in other linker flags section because of it's categories.
            // OTHER_LDFLAGS -lxml2

            Debug.Log("[PostProcessBuild] Adding -lxml2 flag to other linker flags (OTHER_LDFLAGS).");
            xcodeProject.AddBuildProperty(xcodeTarget, "OTHER_LDFLAGS", "-lxml2");
            Debug.Log("[PostProcessBuild] -lxml2 successfully added to other linker flags.");


            // Save the changes to Xcode project file.
            xcodeProject.WriteToFile(xcodeProjectPath);


            //MODIFY Info.plist
            // 3. set ad network required usage descriptions for localisation etc

            string        plistPath = projectPath + "/Info.plist";
            PlistDocument plist     = new PlistDocument();

            plist.ReadFromFile(plistPath);
            PlistElementDict root = plist.root;

            Debug.Log("[PostProcessBuild] Prepare ad network Info.plist update.");

            const string       calenderKey  = "NSCalendarsUsageDescription";
            PlistElementString calenderDesc = new PlistElementString("For Ads Calendar events creation.");

            root[calenderKey] = calenderDesc;

            const string       photoKey  = "NSPhotoLibraryUsageDescription";
            PlistElementString photoDesc = new PlistElementString("For Ads Photos saving.");

            root[photoKey] = photoDesc;

            const string       locationKey  = "NSLocationAlwaysUsageDescription";
            PlistElementString locationDesc = new PlistElementString("Used for localising ads.");

            root[locationKey] = locationDesc;

            Debug.Log("[PostProcessBuild] Complete ad network Info.plist update.");

            //Localisation setup

            const string      localisationKey    = "CFBundleLocalizations";
            PlistElementArray localisationsArray = new PlistElementArray();

            //LocalisationSystem.supportedLanguages.Keys;
            foreach (string langKey in LocalisationSystem.supportedLanguages.Keys)
            {
                localisationsArray.AddString(langKey);
            }
            root[localisationKey] = localisationsArray;


            //UPDATE PLIST

            plist.WriteToFile(plistPath);


            //4. Create Fastline files

            Debug.Log("[PostProcessBuild] Create fastfile files if necessary.");

            string pathString = projectPath + "/fastlane";

            if (File.Exists(pathString) == false)
            {
                System.IO.Directory.CreateDirectory(pathString);
                Debug.Log("Create fastlane folder");
            }

            string gemPath = projectPath + "/Gemfile";

            if (File.Exists(gemPath) == false)
            { // do not overwrite
                Debug.Log("Create Gem file");
                using (StreamWriter outfile =
                           new StreamWriter(gemPath))
                {
                    outfile.WriteLine("source 'https://rubygems.org'");
                    outfile.WriteLine("");
                    outfile.WriteLine("gem 'fastlane'");
                    outfile.WriteLine("");
                }

                AssetDatabase.Refresh();
            }


            string fastfilePath = projectPath + "/fastlane/Fastfile";

            if (File.Exists(fastfilePath) == false)
            { // do not overwrite
                Debug.Log("Create fastlane file");
                using (StreamWriter outfile =
                           new StreamWriter(fastfilePath))
                {
                    outfile.WriteLine("# This file contains the fastlane.tools configuration");
                    outfile.WriteLine("# You can find the documentation at https://docs.fastlane.tools");
                    outfile.WriteLine("# For a list of all available actions, check out");
                    outfile.WriteLine("#     https://docs.fastlane.tools/actions;");
                    outfile.WriteLine("# For a list of all available plugins, check out");
                    outfile.WriteLine("#     https://docs.fastlane.tools/plugins/available-plugins");
                    outfile.WriteLine("");
                    outfile.WriteLine("# Uncomment the line if you want fastlane to automatically update itself");
                    outfile.WriteLine("# update_fastlane");
                    outfile.WriteLine("");
                    outfile.WriteLine("default_platform(:ios)");
                    outfile.WriteLine("");
                    outfile.WriteLine("platform :ios do");
                    outfile.WriteLine("  ################################################################################");
                    outfile.WriteLine("  desc 'Push a new beta build to TestFlight'");
                    outfile.WriteLine("  ################################################################################");
                    outfile.WriteLine("  lane :beta do");
                    outfile.WriteLine("");
                    outfile.WriteLine("    match(");
                    outfile.WriteLine("    app_identifier: [");
                    outfile.WriteLine("        'com.brainbow.speedoku'");
                    outfile.WriteLine("        ],");
                    outfile.WriteLine("    type: 'adhoc',");
                    outfile.WriteLine("    readonly: true,");
                    outfile.WriteLine("    clone_branch_directly: true,");
                    outfile.WriteLine("    shallow_clone: true");
                    outfile.WriteLine("    )");
                    outfile.WriteLine("");
                    outfile.WriteLine("    gym(scheme: 'Unity-iPhone')");
                    outfile.WriteLine("    crashlytics(");
                    outfile.WriteLine("    groups: 'peakteam',");
                    outfile.WriteLine("    api_token: '5b69d6b3859e684d6008664be7aed667b6f458ef',");
                    outfile.WriteLine("    build_secret: '5d951665c2deaa9344d6f767e8b67b36d6db8a7866bbe4967ee2c61f6f835699'");
                    outfile.WriteLine("  )");
                    outfile.WriteLine("  end");
                    outfile.WriteLine("  ################################################################################");
                    outfile.WriteLine("  desc 'Setup certificates and provisioning profiles'");
                    outfile.WriteLine("  ################################################################################");
                    outfile.WriteLine("  lane :certificates do");
                    outfile.WriteLine("");
                    outfile.WriteLine("    match(");
                    outfile.WriteLine("    app_identifier: [");
                    outfile.WriteLine("        'com.brainbow.numberssaga',");
                    outfile.WriteLine("        'com.brainbow.wordpolice',");
                    outfile.WriteLine("        'com.brainbow.quixellogic',");
                    outfile.WriteLine("        'com.brainbow.speedoku'");
                    outfile.WriteLine("        ],");
                    outfile.WriteLine("    type: 'development',");
                    outfile.WriteLine("    clone_branch_directly: true,");
                    outfile.WriteLine("    shallow_clone: true");
                    outfile.WriteLine("    )");
                    outfile.WriteLine("");
                    outfile.WriteLine("    match(");
                    outfile.WriteLine("    app_identifier: [");
                    outfile.WriteLine("        'com.brainbow.numberssaga',");
                    outfile.WriteLine("        'com.brainbow.wordpolice',");
                    outfile.WriteLine("        'com.brainbow.quixellogic',");
                    outfile.WriteLine("        'com.brainbow.speedoku'");
                    outfile.WriteLine("        ],");
                    outfile.WriteLine("    type: 'appstore',");
                    outfile.WriteLine("    readonly: true,");
                    outfile.WriteLine("    clone_branch_directly: true,");
                    outfile.WriteLine("    )");
                    outfile.WriteLine("");
                    outfile.WriteLine("    match(");
                    outfile.WriteLine("    app_identifier: [");
                    outfile.WriteLine("        'com.brainbow.numberssaga',");
                    outfile.WriteLine("        'com.brainbow.wordpolice',");
                    outfile.WriteLine("        'com.brainbow.quixellogic',");
                    outfile.WriteLine("        'com.brainbow.speedoku'");
                    outfile.WriteLine("        ],");
                    outfile.WriteLine("    type: 'adhoc',");
                    outfile.WriteLine("    force: false,");
                    outfile.WriteLine("    clone_branch_directly: true,");
                    outfile.WriteLine("    )");
                    outfile.WriteLine("");
                    outfile.WriteLine("  end");
                    outfile.WriteLine("end");
                    outfile.WriteLine("");
                }

                AssetDatabase.Refresh();
            }

            string matchfilePath = projectPath + "/fastlane/Matchfile";

            if (File.Exists(matchfilePath) == false)
            { // do not overwrite
                Debug.Log("Create Match file");
                using (StreamWriter outfile =
                           new StreamWriter(matchfilePath))
                {
                    outfile.WriteLine("git_url 'https://github.com/brainbow/certificates.git'");
                    outfile.WriteLine("");
                    outfile.WriteLine("team_id 'TGZW3NA5J5'");
                    outfile.WriteLine("");
                    outfile.WriteLine("# app_identifier 'tools.fastlane.app'");
                    outfile.WriteLine("username '*****@*****.**' # Your Apple Developer Portal username");
                    outfile.WriteLine("");
                }

                AssetDatabase.Refresh();
            }

            string appPath = projectPath + "/fastlane/Appfile";

            if (File.Exists(appPath) == false)
            { // do not overwrite
                Debug.Log("Create App file");
                using (StreamWriter outfile =
                           new StreamWriter(appPath))
                {
                    outfile.WriteLine("app_identifier('com.brainbow.quixellogic') # The bundle identifier of your app");
                    outfile.WriteLine("apple_id('*****@*****.**') # Your Apple email address");
                    outfile.WriteLine("");
                    outfile.WriteLine("itc_team_id('1334403') # App Store Connect Team ID");
                    outfile.WriteLine("team_id('TGZW3NA5J5') # Developer Portal Team IDe");
                    outfile.WriteLine("");
                    outfile.WriteLine("# For more information about the Appfile, see:");
                    outfile.WriteLine("#     https://docs.fastlane.tools/advanced/#appfile");
                    outfile.WriteLine("");
                }

                AssetDatabase.Refresh();
            }

            Debug.Log("[PostProcessBuild] Fastfile files created.");
            //#endif
        }
Ejemplo n.º 9
0
 public void SetString(string key, string val)
 {
     values[key] = new PlistElementString(val);
 }
Ejemplo n.º 10
0
        private static void UpdateIOSPlist(string path, Yodo1AdSettings settings)
        {
            string        plistPath = Path.Combine(path, "Info.plist");
            PlistDocument plist     = new PlistDocument();

            plist.ReadFromString(File.ReadAllText(plistPath));

            //Get Root
            PlistElementDict rootDict          = plist.root;
            PlistElementDict transportSecurity = rootDict.CreateDict("NSAppTransportSecurity");

            transportSecurity.SetBoolean("NSAllowsArbitraryLoads", true);

            //Set SKAdNetwork
            PlistElementArray skItem = rootDict.CreateArray("SKAdNetworkItems");

            foreach (string sk in mSKAdNetworkId)
            {
                PlistElementDict skDic = skItem.AddDict();
                skDic.SetString("SKAdNetworkIdentifier", sk);
            }

            //Set AppLovinSdkKey
            rootDict.SetString("AppLovinSdkKey", Yodo1EditorConstants.DEFAULT_APPLOVIN_SDK_KEY);

            //Set AdMob APP Id
            if (settings.iOSSettings.GlobalRegion)
            {
                rootDict.SetString("GADApplicationIdentifier", settings.iOSSettings.AdmobAppID);
            }

            PlistElementString privacy = (PlistElementString)rootDict["NSLocationAlwaysUsageDescription"];

            if (privacy == null)
            {
                rootDict.SetString("NSLocationAlwaysUsageDescription", "Some ad content may require access to the location for an interactive ad experience.");
            }

            PlistElementString privacy1 = (PlistElementString)rootDict["NSLocationWhenInUseUsageDescription"];

            if (privacy1 == null)
            {
                rootDict.SetString("NSLocationWhenInUseUsageDescription", "Some ad content may require access to the location for an interactive ad experience.");
            }

            PlistElementString attPrivacy = (PlistElementString)rootDict["NSUserTrackingUsageDescription"];

            if (attPrivacy == null)
            {
                rootDict.SetString("NSUserTrackingUsageDescription", "This identifier will be used to deliver personalized ads to you.");
            }

            PlistElementString calendarsPrivacy = (PlistElementString)rootDict["NSCalendarsUsageDescription"];

            if (calendarsPrivacy == null)
            {
                rootDict.SetString("NSCalendarsUsageDescription", "The application wants to use your calendar. Is that allowed?");
            }

            File.WriteAllText(plistPath, plist.WriteToString());
        }
Ejemplo n.º 11
0
    public static void OnPostprocessBuild(BuildTarget buildTarget, string path)
    {
        if (buildTarget == BuildTarget.iOS)
        {
            string projPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj";

            PBXProject proj = new PBXProject();
            proj.ReadFromFile(projPath);
            string target = proj.TargetGuidByName("Unity-iPhone");

            // Add Frameworks
            proj.AddFrameworkToProject(target, "Accelerate.framework", false);
            proj.AddFrameworkToProject(target, "Metal.framework", false);
            proj.AddFrameworkToProject(target, "GLKit.framework", false);
            proj.AddFrameworkToProject(target, "ARKit.framework", true);

            // Disable use of Bitcode
            proj.SetBuildProperty(target, "ENABLE_BITCODE", "NO");

            // Only generate 64bit variants, so set Valid Archs to only "arm64"
            //proj.SetBuildProperty(target, "ARCHS", "arm64");
            //proj.SetBuildProperty(target, "VALID_ARCHS", "arm64");
            proj.UpdateBuildProperty(target, "ARCHS",
                                     new string[] {}, new string[] { "armv7", "armv7s", "armv7" });
            proj.UpdateBuildProperty(target, "VALID_ARCHS",
                                     new string[] { "arm64" }, new string[] { "armv7", "armv7s" });

            // Compile libz and xml2 along with project
            proj.UpdateBuildProperty(target, "OTHER_LDFLAGS",
                                     new string[] { "-lz", "-lxml2" }, new string[] {});

            proj.WriteToFile(projPath);

            // Since iOS 10 it's necessary to add a reason for accessing the
            // camera to Info.plist. Newer version of Unity allow to set the
            // usage description inside the editor. For older Versions of
            // Unity, we add a default value automatically.

            // Get plist
            string        plistPath = path + "/Info.plist";
            PlistDocument plist     = new PlistDocument();
            plist.ReadFromString(File.ReadAllText(plistPath));

            // Get root
            PlistElementDict rootDict = plist.root;

            // Set usage description, if not set already
            string cameraUsageDescriptionKey =
                "Privacy - Camera Usage Description";
            string cameraUsageDescriptionValue =
                "Augmented Reality";
            PlistElementString cameraUsageDescriptionEl =
                (PlistElementString)rootDict[cameraUsageDescriptionKey];
            if (cameraUsageDescriptionEl == null)
            {
                rootDict.SetString(cameraUsageDescriptionKey,
                                   cameraUsageDescriptionValue);
                File.WriteAllText(plistPath, plist.WriteToString());
            }
            else if (String.IsNullOrEmpty(cameraUsageDescriptionEl.value))
            {
                cameraUsageDescriptionEl.value = cameraUsageDescriptionValue;
                File.WriteAllText(plistPath, plist.WriteToString());
            }
        }
    }
Ejemplo n.º 12
0
    public static void AddDataToPlist(BuildTarget buildTarget, string pathToBuiltProject)
    {
        if (buildTarget == BuildTarget.iOS)
        {
                        #if UNITY_IOS
            //Build Data From Google Services File
            PlistDocument googlePlist = new PlistDocument();
            googlePlist.ReadFromString(File.ReadAllText(pathToBuiltProject + "/" + googleInfoPlistFilePath));
            string fireAppID = googlePlist.root ["REVERSED_CLIENT_ID"].AsString();

            // Get plist
            string        plistPath = pathToBuiltProject + "/Info.plist";
            PlistDocument plist     = new PlistDocument();
            plist.ReadFromString(File.ReadAllText(plistPath));

            // Get root
            PlistElementDict rootDict = plist.root;


            //1. Build Data
            PlistElementArray bundleUrlSchemaArr1 = new PlistElementArray();
            bundleUrlSchemaArr1.AddString(fireAppID);

            PlistElementArray bundleUrlSchemaArr2 = new PlistElementArray();
            bundleUrlSchemaArr2.AddString(Application.identifier);

            var               bundleUrlRootKey = "CFBundleURLTypes";
            PlistElement      bundleUrlData    = rootDict [bundleUrlRootKey];
            PlistElementArray bundleUrlAsArray = null;
            if (bundleUrlData == null)
            {
                bundleUrlAsArray = new PlistElementArray();
            }
            else
            {
                bundleUrlAsArray = bundleUrlData.AsArray();
            }

            //2..
            PlistElementDict bundleUrlItem1 = new PlistElementDict();
            bundleUrlItem1 ["CFBundleTypeRole"]   = new PlistElementString("Editor");
            bundleUrlItem1 ["CFBundleURLName"]    = new PlistElementString("google");
            bundleUrlItem1 ["CFBundleURLSchemes"] = bundleUrlSchemaArr1;

            bundleUrlAsArray.values.Add(bundleUrlItem1);

            //3.. (A hack for login crash issue)
            PlistElementDict bundleUrlItem2 = new PlistElementDict();
            bundleUrlItem2 ["CFBundleTypeRole"]   = new PlistElementString("Editor");
            bundleUrlItem2 ["CFBundleURLName"]    = new PlistElementString("lcgoogle");
            bundleUrlItem2 ["CFBundleURLSchemes"] = bundleUrlSchemaArr2;

            bundleUrlAsArray.values.Add(bundleUrlItem2);

            //3..
            rootDict [bundleUrlRootKey] = bundleUrlAsArray;

            // // ~~ Add GoogleSignIn Data // //


            // Write to file
            File.WriteAllText(plistPath, plist.WriteToString());

            Debug.Log("LCGoogleSignIn: iOS: AddDataToPlist for callbacks: Success");
                        #endif
        }
    }