public static void OnPostprocessBuild(BuildTarget buildTarget, string path) { #if UNITY_IPHONE string projectPath = path + "/Unity-iPhone.xcodeproj/project.pbxproj"; PBXProject project = new PBXProject(); project.ReadFromString(File.ReadAllText(projectPath)); // This is the project name that Unity generates for iOS, isn't editable until after post processing string target = project.TargetGuidByName(PBXProject.GetUnityTargetName()); #if UNITY_5_0 project.AddBuildProperty(target, "FRAMEWORK_SEARCH_PATHS", "$(PROJECT_DIR)/Frameworks/Plugins/iOS"); #else CopyAndReplaceDirectory("Assets/Plugins/iOS/FiksuSDK.bundle", Path.Combine(path, "Frameworks/FiksuSDK.bundle")); project.AddFileToBuild(target, project.AddFile("Frameworks/FiksuSDK.bundle", "Frameworks/FiksuSDK.bundle", PBXSourceTree.Source)); CopyAndReplaceDirectory("Assets/Plugins/iOS/FiksuSDK.framework", Path.Combine(path, "Frameworks/FiksuSDK.framework")); project.AddFileToBuild(target, project.AddFile("Frameworks/FiksuSDK.framework", "Frameworks/FiksuSDK.framework", PBXSourceTree.Source)); project.SetBuildProperty(target, "FRAMEWORK_SEARCH_PATHS", "$(inherited)"); project.AddBuildProperty(target, "FRAMEWORK_SEARCH_PATHS", "$(PROJECT_DIR)/Frameworks"); #endif project.AddFrameworkToProject(target, "AdSupport.framework", true); project.AddFrameworkToProject(target, "StoreKit.framework", true); project.AddFrameworkToProject(target, "Security.framework", true); project.AddFrameworkToProject(target, "SystemConfiguration.framework", false); project.AddFrameworkToProject(target, "MessageUI.framework", false); File.WriteAllText(projectPath, project.WriteToString()); #endif }
public static void OnPostProcessBuild( BuildTarget buildTarget, string buildPath ) { #if UNITY_5 if (buildTarget == BuildTarget.iOS) #else if (buildTarget == BuildTarget.iPhone) #endif { var projPath = PBXProject.GetPBXProjectPath( buildPath ); PBXProject proj = new PBXProject(); proj.ReadFromString( File.ReadAllText( projPath ) ); var targetGuid = proj.TargetGuidByName( "Unity-iPhone" ); var instance = ScriptableObject.CreateInstance<ICadePluginPath>(); var pluginPath = Path.GetDirectoryName( AssetDatabase.GetAssetPath( MonoScript.FromScriptableObject( instance ) ) ); ScriptableObject.DestroyImmediate( instance ); var targetPath = Path.Combine( "Libraries", pluginPath.Substring( 7 ) ); Directory.CreateDirectory( Path.Combine( buildPath, targetPath ) ); foreach (var fileName in sourceFiles) { var sourcePath = Path.Combine( pluginPath, fileName ); var targetFile = Path.Combine( targetPath, fileName ); File.Copy( sourcePath, Path.Combine( buildPath, targetFile ), true ); proj.AddFileToBuild( targetGuid, proj.AddFile( targetFile, targetFile, PBXSourceTree.Source ) ); } File.WriteAllText( projPath, proj.WriteToString() ); } }
static void LinkBinaryWithLibraries(PBXProject pbxProject, string targetGuid, string frameworkName) { //"true" will add the framework in the "Link Binary With Libraries" section with status "Optional", "false" will be "Required". pbxProject.AddFrameworkToProject(targetGuid, frameworkName, false); }
static void EnableCppModules(PBXProject pbxProject) { pbxProject.AddBuildProperty(pbxProject.GetUnityMainTargetGuid(), "CLANG_ENABLE_MODULES", "YES"); pbxProject.AddBuildProperty(pbxProject.GetUnityFrameworkTargetGuid(), "CLANG_ENABLE_MODULES", "YES"); }
private static void CopyFile(string XCodeRelativePath, string sourcePath, string pathToBuiltProject, PBXProject proj, string targetGUID) { var dstPath = Path.Combine(pathToBuiltProject, XCodeRelativePath); var rootPath = Path.GetDirectoryName(dstPath); if (!Directory.Exists(rootPath)) { Directory.CreateDirectory(rootPath); } File.Copy(sourcePath, dstPath); var name = proj.AddFile(XCodeRelativePath, XCodeRelativePath, PBXSourceTree.Source); proj.AddFileToBuild(targetGUID, name); }
private static void AddUsrLib(PBXProject proj, string targetGuid, string framework) { string fileGuid = proj.AddFile("usr/lib/" + framework, "Frameworks/" + framework, PBXSourceTree.Sdk); proj.AddFileToBuild(targetGuid, fileGuid); }
internal static void SetDefaultWatchAppDebugBuildFlags(this PBXProject proj, string configGuid) { SetBuildFlagsFromDict(proj, configGuid, watchAppDebugBuildFlags); }
internal static void SetDefaultAppExtensionDebugBuildFlags(this PBXProject proj, string configGuid) { SetBuildFlagsFromDict(proj, configGuid, appExtensionDebugBuildFlags); }
public void AddMultipleCapabilitiesWithEntitlementWorks() { SetupTestProject(); ResetGuidGenerator(); var capManager = new ProjectCapabilityManager(PBXProject.GetPBXProjectPath(GetTestOutputPath()), "test.entitlements", PBXProject.GetUnityTargetName()); capManager.AddiCloud(true, false, new string[] {}); capManager.AddApplePay(new string[] { "test1", "test2" }); capManager.AddSiri(); capManager.WriteToFile(); TestOutputProject(capManager.project, "add_multiple_entitlements.pbxproj"); TestOutput("test.entitlements", "add_multiple_entitlements.entitlements"); }
public void AddMultipleCapabilitiesWorks() { SetupTestProject(); ResetGuidGenerator(); var capManager = new ProjectCapabilityManager(PBXProject.GetPBXProjectPath(GetTestOutputPath()), "test.entitlements", PBXProject.GetUnityTargetName()); capManager.AddGameCenter(); capManager.AddInAppPurchase(); capManager.AddMaps(MapsOptions.Airplane); capManager.WriteToFile(); TestOutputProject(capManager.project, "add_multiple.pbxproj"); }
public void AddWirelessAccessoryConfigurationWorks() { SetupTestProject(); ResetGuidGenerator(); var capManager = new ProjectCapabilityManager(PBXProject.GetPBXProjectPath(GetTestOutputPath()), "test.entitlements", PBXProject.GetUnityTargetName()); capManager.AddWirelessAccessoryConfiguration(); capManager.WriteToFile(); TestOutputProject(capManager.project, "add_wirelessaccessory.pbxproj"); TestOutput("test.entitlements", "add_wirelessaccessory.entitlements"); }
public void AddHealthKitWorks() { SetupTestProject(); ResetGuidGenerator(); var capManager = new ProjectCapabilityManager(PBXProject.GetPBXProjectPath(GetTestOutputPath()), "test.entitlements", PBXProject.GetUnityTargetName()); capManager.AddHealthKit(); capManager.WriteToFile(); TestOutputProject(capManager.project, "add_healthkit.pbxproj"); TestOutput("test.entitlements", "add_healthkit.entitlements"); TestOutput("Info.plist", "add_healthkit.plist"); }
public void AddDataProtectionWorks() { SetupTestProject(); ResetGuidGenerator(); var capManager = new ProjectCapabilityManager(PBXProject.GetPBXProjectPath(GetTestOutputPath()), "test.entitlements", PBXProject.GetUnityTargetName()); capManager.AddDataProtection(); capManager.WriteToFile(); TestOutputProject(capManager.project, "add_dataprotection.pbxproj"); TestOutput("test.entitlements", "add_dataprotection.entitlements"); }
public void AddAppGroupsWorks() { SetupTestProject(); ResetGuidGenerator(); var capManager = new ProjectCapabilityManager(PBXProject.GetPBXProjectPath(GetTestOutputPath()), "test.entitlements", PBXProject.GetUnityTargetName()); capManager.AddAppGroups(new string[] { "test1", "test2" }); capManager.WriteToFile(); TestOutputProject(capManager.project, "add_appgroups.pbxproj"); TestOutput("test.entitlements", "add_appgroups.entitlements"); }
public void AddAssociatedDomainsWorks() { SetupTestProject(); ResetGuidGenerator(); var capManager = new ProjectCapabilityManager(PBXProject.GetPBXProjectPath(GetTestOutputPath()), "test.entitlements", PBXProject.GetUnityTargetName()); capManager.AddAssociatedDomains(new string[] { "webcredentials:example.com", "webcredentials:example2.com" }); capManager.WriteToFile(); TestOutputProject(capManager.project, "add_associateddomains.pbxproj"); TestOutput("test.entitlements", "add_associateddomains.entitlements"); }
public void AddiCloudWorks() { SetupTestProject(); ResetGuidGenerator(); var capManager = new ProjectCapabilityManager(PBXProject.GetPBXProjectPath(GetTestOutputPath()), "test.entitlements", PBXProject.GetUnityTargetName()); capManager.AddiCloud(true, false, new string[] {}); capManager.WriteToFile(); TestOutputProject(capManager.project, "add_icloud.pbxproj"); TestOutput("test.entitlements", "add_icloud.entitlements"); }
public void AddInterAppAudioWorks() { SetupTestProject(); ResetGuidGenerator(); var capManager = new ProjectCapabilityManager(PBXProject.GetPBXProjectPath(GetTestOutputPath()), "test.entitlements", PBXProject.GetUnityTargetName()); capManager.AddInterAppAudio(); capManager.WriteToFile(); TestOutputProject(capManager.project, "add_interappaudio.pbxproj"); TestOutput("test.entitlements", "add_interappaudio.entitlements"); }
private static void AddNotificationServiceExtension(PBXProject project, string path) { #if !UNITY_CLOUD_BUILD var projectPath = PBXProject.GetPBXProjectPath(path); var mainTargetGUID = GetPBXProjectTargetGUID(project); var extensionTargetName = NotificationServiceExtensionTargetName; var exisitingPlistFile = CreateNotificationExtensionPlistFile(path); // If file exisits then the below has been completed before from another build // The below will not be updated on Append builds // Changes would most likely need to be made to support Append builds if (exisitingPlistFile) { return; } var extensionGUID = PBXProjectExtensions.AddAppExtension( project, mainTargetGUID, extensionTargetName, PlayerSettings.GetApplicationIdentifier(BuildTargetGroup.iOS) + "." + extensionTargetName, extensionTargetName + "/" + "Info.plist" // Unix path as it's used by Xcode ); AddNotificationServiceSourceFilesToTarget(project, extensionGUID, path); foreach (var framework in FrameworksToAdd) { project.AddFrameworkToProject(extensionGUID, framework, true); } // Makes it so that the extension target is Universal (not just iPhone) and has an iOS 10 deployment target project.SetBuildProperty(extensionGUID, "TARGETED_DEVICE_FAMILY", "1,2"); project.SetBuildProperty(extensionGUID, "IPHONEOS_DEPLOYMENT_TARGET", "10.0"); project.SetBuildProperty(extensionGUID, "ARCHS", "$(ARCHS_STANDARD)"); project.SetBuildProperty(extensionGUID, "DEVELOPMENT_TEAM", PlayerSettings.iOS.appleDeveloperTeamID); project.AddBuildProperty(extensionGUID, "LIBRARY_SEARCH_PATHS", $"$(PROJECT_DIR)/Libraries/{PluginLibrariesPath.Replace("\\", "/")}"); project.WriteToFile(projectPath); // Add libOneSignal.a to the OneSignalNotificationServiceExtension target var contents = File.ReadAllText(projectPath); // This method only modifies the PBXProject string passed in (contents). // After this method finishes, we must write the contents string to disk InsertStaticFrameworkIntoTargetBuildPhaseFrameworks("libOneSignal", "CD84C25F20742FAB0035D524", extensionGUID, ref contents, project); File.WriteAllText(projectPath, contents); AddOrUpdateEntitlements( path, project, extensionGUID, extensionTargetName, new HashSet <EntitlementOptions> { EntitlementOptions.AppGroups } ); #endif }
internal static void SetDefaultWatchExtensionReleaseBuildFlags(this PBXProject proj, string configGuid) { SetBuildFlagsFromDict(proj, configGuid, watchExtensionReleaseBuildFlags); }
// Takes a static framework that is already linked to a different target in the project and links it to the specified target private static void InsertStaticFrameworkIntoTargetBuildPhaseFrameworks(string staticFrameworkName, string frameworkGuid, string target, ref string contents, PBXProject project) { #if !UNITY_CLOUD_BUILD // In order to find the fileRef, find the PBXBuildFile objects section of the PBXProject var splitString = " /* " + staticFrameworkName + ".a in Frameworks */ = {isa = PBXBuildFile; fileRef = "; var splitComponents = contents.Split(new string[] { splitString }, StringSplitOptions.None); if (splitComponents.Length < 2) { Debug.LogError( "(error 1) OneSignal's Build Post Processor has encountered an error while attempting to add the Notification Extension Service to your project. Please create an issue on our OneSignal-Unity-SDK repo on GitHub."); return; } var afterSplit = splitComponents[1]; // To get the fileRef of the static framework, read the last 24 characters of the beforeSplit string var fileRefBuilder = new StringBuilder(); for (int i = 0; i < 24; i++) { fileRefBuilder.Append(afterSplit[i]); } var fileRef = fileRefBuilder.ToString(); project.AddFileToBuild(target, fileRef); // Add the framework as an additional object in PBXBuildFile objects contents = contents.Replace("; fileRef = " + fileRef + " /* " + staticFrameworkName + ".a */; };", "; fileRef = " + fileRef + " /* " + staticFrameworkName + ".a */; };\n\t\t" + frameworkGuid + " /* " + staticFrameworkName + ".a in Frameworks */ = {isa = PBXBuildFile; fileRef = " + fileRef + " /* " + staticFrameworkName + ".a */; };"); // Find the build phase ID number var targetBuildPhaseId = project.GetFrameworksBuildPhaseByTarget(target); string[] components = contents.Split( new string[] { targetBuildPhaseId + " /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = " }, StringSplitOptions.None); if (components.Length < 2) { Debug.LogError( "(error 2) OneSignal's Build Post Processor has encountered an error while attempting to add the Notification Extension Service to your project. Please create an issue on our OneSignal-Unity-SDK repo on GitHub."); return; } var buildPhaseString = components[1]; var replacer = new StringBuilder(); for (int i = 0; i < buildPhaseString.Length; i++) { var seq = buildPhaseString[i]; if (char.IsNumber(seq)) { replacer.Append(seq); } else { break; } } // insert the framework into the PBXFrameworksBuildPhase var beginString = targetBuildPhaseId + " /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = " + replacer.ToString() + ";\n\t\t\tfiles = ("; contents = contents.Replace(beginString, beginString + "\n" + "\t\t\t\t" + frameworkGuid + " /* " + staticFrameworkName + ".a in Frameworks */,"); #endif }
public static void ChangeXcodeProject(string pathToBuiltProject) { // Get xcodeproj string pathToProject = pathToBuiltProject + "/Unity-iPhone.xcodeproj/project.pbxproj"; string[] lines = File.ReadAllLines(pathToProject); // We'll open/replace project.pbxproj for writing and iterate over the old // file in memory, copying the original file and inserting every extra we need. // Create new file and open it for read and write, if the file exists overwrite it. FileStream fileProject = new FileStream(pathToProject, FileMode.Create); fileProject.Close(); // Will be used for writing StreamWriter fCurrentXcodeProjFile = new StreamWriter(pathToProject); // Write all lines to new file and enable objective C exceptions foreach (string line in lines) { if (line.Contains("GCC_ENABLE_OBJC_EXCEPTIONS")) { fCurrentXcodeProjFile.Write("\t\t\t\tGCC_ENABLE_OBJC_EXCEPTIONS = YES;\n"); } else if (line.Contains("GCC_ENABLE_CPP_EXCEPTIONS")) { fCurrentXcodeProjFile.Write("\t\t\t\tGCC_ENABLE_CPP_EXCEPTIONS = YES;\n"); } else if (line.Contains("CLANG_ENABLE_MODULES")) { fCurrentXcodeProjFile.Write("\t\t\t\tCLANG_ENABLE_MODULES = YES;\n"); } else { fCurrentXcodeProjFile.WriteLine(line); } } // Close file fCurrentXcodeProjFile.Close(); // Add frameworks PBXProject proj = new PBXProject(); proj.ReadFromString(File.ReadAllText(pathToProject)); string target = ""; #if UNITY_2019_3_OR_NEWER target = proj.GetUnityFrameworkTargetGuid(); #else target = proj.TargetGuidByName("Unity-iPhone"); #endif #if UNITY_2017_1_OR_NEWER if (!proj.ContainsFramework(target, "AdSupport.framework")) { proj.AddFrameworkToProject(target, "AdSupport.framework", false); } if (!proj.ContainsFramework(target, "CoreTelephony.framework")) { proj.AddFrameworkToProject(target, "CoreTelephony.framework", false); } if (!proj.ContainsFramework(target, "CoreSpotlight.framework")) { proj.AddFrameworkToProject(target, "CoreSpotlight.framework", false); } if (!proj.ContainsFramework(target, "Security.framework")) { proj.AddFrameworkToProject(target, "Security.framework", false); } if (!proj.ContainsFramework(target, "WebKit.framework")) { proj.AddFrameworkToProject(target, "WebKit.framework", false); } #else if (!proj.HasFramework("AdSupport.framework")) { proj.AddFrameworkToProject(target, "AdSupport.framework", false); } if (!proj.HasFramework("CoreTelephony.framework")) { proj.AddFrameworkToProject(target, "CoreTelephony.framework", false); } if (!proj.HasFramework("CoreSpotlight.framework")) { proj.AddFrameworkToProject(target, "CoreSpotlight.framework", false); } if (!proj.HasFramework("Security.framework")) { proj.AddFrameworkToProject(target, "Security.framework", false); } #endif File.WriteAllText(pathToProject, proj.WriteToString()); }
/* * Unity 2019.3 made large changes to the Xcode build system / API. * There is now two targets; * - Unity-Iphone (Main) * - UnityFramework * - Plugins are now added this instead of the main target */ #if UNITY_2019_3_OR_NEWER /// <remarks> /// var projectUUID = project.GetUnityMainTargetGuid(); /// return project.GetBuildPhaseName(projectUUID); /// The above always returns null, using a static value for now. /// </remarks> private static string GetPBXProjectTargetName(PBXProject project) => DefaultProjectTargetName;
public static void OnPostprocessBuild(BuildTarget target, string projectPath) { var pbxProjPath = PBXProject.GetPBXProjectPath(projectPath); var proj = new PBXProject(); proj.ReadFromFile(pbxProjPath); #if UNITY_2019_3_OR_NEWER var targetGuid = proj.GetUnityMainTargetGuid(); var frameworkTargetGuid = proj.GetUnityFrameworkTargetGuid(); #else var targetGuid = proj.TargetGuidByName("Unity-iPhone"); var frameworkTargetGuid = proj.TargetGuidByName("Unity-iPhone"); #endif RegisterAppLanguages(); AddFlags(proj, targetGuid); AddLibraries(proj, targetGuid); AddFrameworks(proj, frameworkTargetGuid, target); AddEmbeddedFrameworks(proj, targetGuid); AddPlistVariables(projectPath); ApplyBuildSettings(proj, frameworkTargetGuid); CopyAssetFiles(proj, projectPath, targetGuid); AddShellScriptBuildPhase(proj, targetGuid); proj.WriteToFile(pbxProjPath); var capManager = new ProjectCapabilityManager(pbxProjPath, ISD_Settings.ENTITLEMENTS_FILE_NAME, "Unity-iPhone"); AddCapabilities(capManager); capManager.WriteToFile(); //Some API simply does not work so on this block we are applying a workaround //after Unity deploy scrips has stopped working //Adding Embedded Frameworks foreach (var framework in ISD_Settings.Instance.EmbededFrameworks) { var contents = File.ReadAllText(pbxProjPath); var pattern = "(?<=Embed Frameworks)(?:.*)(\\/\\* " + framework.FileName + "\\ \\*\\/)(?=; };)"; var oldText = "/* " + framework.FileName + " */"; var updatedText = "/* " + framework.FileName + " */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }"; contents = Regex.Replace(contents, pattern, m => m.Value.Replace(oldText, updatedText)); File.WriteAllText(pbxProjPath, contents); } var entitlementsPath = projectPath + "/" + ISD_Settings.ENTITLEMENTS_FILE_NAME; if (ISD_Settings.Instance.EntitlementsMode == ISD_EntitlementsGenerationMode.Automatic) { if (ISD_Settings.Instance.Capability.iCloud.Enabled) { if (ISD_Settings.Instance.Capability.iCloud.keyValueStorage && !ISD_Settings.Instance.Capability.iCloud.iCloudDocument) { var entitlements = new PlistDocument(); entitlements.ReadFromFile(entitlementsPath); var plistVariable = new PlistElementArray(); entitlements.root["com.apple.developer.icloud-container-identifiers"] = plistVariable; entitlements.WriteToFile(entitlementsPath); } } } else { if (ISD_Settings.Instance.EntitlementsFile != null) { var entitlementsContentPath = SA_AssetDatabase.GetAbsoluteAssetPath(ISD_Settings.Instance.EntitlementsFile); string contents = File.ReadAllText(entitlementsContentPath); File.WriteAllText(entitlementsPath, contents); } else { Debug.LogWarning("ISD: EntitlementsMode set to Manual but no file provided"); } } }
private static string GetPBXProjectTargetGUID(PBXProject project) => project.GetUnityMainTargetGuid();
static void TieBridgingHeader(PBXProject pbxProject, string targetGuid) { pbxProject.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO"); pbxProject.SetBuildProperty(targetGuid, "SWIFT_OBJC_BRIDGING_HEADER", "Libraries/Plugins/iOS/Source/UnityPlugin-Bridging-Header.h"); pbxProject.SetBuildProperty(targetGuid, "SWIFT_OBJC_INTERFACE_HEADER_NAME", "UnityController.h"); }
private static string GetPBXProjectUnityFrameworkGUID(PBXProject project) => project.GetUnityFrameworkTargetGuid();
static void EnableObjectiveCExceptions(PBXProject pbxProject) { pbxProject.SetBuildProperty(pbxProject.GetUnityMainTargetGuid(), "GCC_ENABLE_OBJC_EXCEPTIONS", "YES"); pbxProject.SetBuildProperty(pbxProject.GetUnityFrameworkTargetGuid(), "GCC_ENABLE_OBJC_EXCEPTIONS", "YES"); }
private static string GetPBXProjectTargetName(PBXProject project) => PBXProject.GetUnityTargetName();
public XcodeProjMod(string buildPath) { m_buildPath = buildPath; m_projectPath = PBXProject.GetPBXProjectPath(buildPath); }
private static string GetPBXProjectTargetGUID(PBXProject project) => project.TargetGuidByName(PBXProject.GetUnityTargetName());
/// <summary> /// Visits the specified element. /// </summary> /// <param name = "element">The element.</param> public void Visit(PBXProject element) { this.Add (element); }
private static string GetPBXProjectUnityFrameworkGUID(PBXProject project) => GetPBXProjectTargetGUID(project);
public void AddBackgroundModesWorks() { SetupTestProject(); ResetGuidGenerator(); var capManager = new ProjectCapabilityManager(PBXProject.GetPBXProjectPath(GetTestOutputPath()), "test.entitlements", PBXProject.GetUnityTargetName()); capManager.AddBackgroundModes(BackgroundModesOptions.BackgroundFetch); capManager.WriteToFile(); TestOutputProject(capManager.project, "add_backgroundmodes.pbxproj"); TestOutput("Info.plist", "add_backgroundmodes.plist"); }
public XCProject( string filePath ) : this() { if( !System.IO.Directory.Exists( filePath ) ) { Debug.LogWarning( "Path does not exists." ); return; } if( filePath.EndsWith( ".xcodeproj" ) ) { this.projectRootPath = Path.GetDirectoryName( filePath ); this.filePath = filePath; } else { string[] projects = System.IO.Directory.GetDirectories( filePath, "*.xcodeproj" ); if( projects.Length == 0 ) { Debug.LogWarning( "Error: missing xcodeproj file" ); return; } this.projectRootPath = filePath; this.filePath = projects[ 0 ]; } projectFileInfo = new FileInfo( Path.Combine( this.filePath, "project.pbxproj" ) ); StreamReader streamReader = projectFileInfo.OpenText(); string contents = streamReader.ReadToEnd(); streamReader.Close(); PBXParser parser = new PBXParser(); _datastore = parser.Decode( contents ); if( _datastore == null ) { throw new System.Exception( "Project file not found at file path " + filePath ); } if( !_datastore.ContainsKey( "objects" ) ) { Debug.Log( "Errore " + _datastore.Count ); return; } _objects = (PBXDictionary)_datastore["objects"]; modified = false; _rootObjectKey = (string)_datastore["rootObject"]; if( !string.IsNullOrEmpty( _rootObjectKey ) ) { _project = new PBXProject( _rootObjectKey, (PBXDictionary)_objects[ _rootObjectKey ] ); _rootGroup = new PBXGroup( _rootObjectKey, (PBXDictionary)_objects[ _project.mainGroupID ] ); } else { Debug.LogWarning( "Error: project has no root object" ); _project = null; _rootGroup = null; } }