public static void OnBuildPostprocess(IBuildProcessor buildProcessor) { if (buildProcessor is iOSBuildProcessor) { OnBuildPostprocess(buildProcessor as iOSBuildProcessor); } }
/// <summary> /// A helper method subclasses can use to implement the <see cref="Processor"/ > logic. /// </summary> /// <param name="processor"> /// The build processor instance to assign to the <see cref="Processor"/ > property. /// </param> public static void OnPreprocess(IBuildProcessor processor) { if (BuildProcessor.Processor != null) { Debug.LogError(string.Format("Invalid operation: Processor already exists: {0}", BuildProcessor.Processor)); return; } if (processor == null) { Debug.LogError(string.Format("Invalid processor: {0}", processor)); } BuildProcessor.Processor = processor; try { BuildProcessor.Processor.PreprocessBegin(); BuildProcessor.Processor.Preprocess(); OnBuildPreprocessAttribute.Invoke(BuildProcessor.Processor); BuildProcessor.Processor.PreprocessEnd(); } catch (System.Exception e) { Debug.LogException(e); BuildProcessor.Processor = null; throw e; } }
public static void OnBuildPostprocess(IBuildProcessor instance) { #if SAGO_IOS_DEMO if (instance is iOSBuildProcessor) { iOSBuildProcessor processor; processor = instance as iOSBuildProcessor; Dictionary <string, object> dict = processor.ReadPlist(); dict["CFBundleIdentifier"] = string.Format("{0}.demo", dict["CFBundleIdentifier"]); processor.WritePlist(dict); } #endif #if SAGO_TVOS_DEMO && UNITY_TVOS && UNITY_5_3_OR_NEWER if (instance is SagoBuildEditor.tvOS.tvOSBuildProcessor) { SagoBuildEditor.tvOS.tvOSBuildProcessor processor; processor = instance as SagoBuildEditor.tvOS.tvOSBuildProcessor; Dictionary <string, object> dict = processor.ReadPlist(); dict["CFBundleIdentifier"] = string.Format("{0}.demo", dict["CFBundleIdentifier"]); processor.WritePlist(dict); } #endif }
public static void UpdateSettingsBundle(IBuildProcessor processor) { List <object> prefs = new List <object>(); LocalizationDictionary localization = CreateLocalizationDictionary(); foreach (var type in FindSettingsGroupTypes()) { List <object> tempPrefs = new List <object>(); AddSettingsGroup(type, tempPrefs, localization); AddToggleSwitch(type, tempPrefs, localization); AddMultiValue(type, tempPrefs, localization); if (tempPrefs.Count > 1) { for (int i = 0; i < tempPrefs.Count; i++) { prefs.Add(tempPrefs[i]); } } } WriteLocalization(localization); WritePrefs(prefs); UnityEditor.AssetDatabase.Refresh(); }
public static void PreprocessAndroidManifest(IBuildProcessor processor) { if (processor is AndroidBuildProcessor) { try { string submodulePath; submodulePath = SubmoduleMap.GetSubmodulePath(typeof(SagoPlatform.SubmoduleInfo)); string srcRoot; srcRoot = Path.Combine(submodulePath, "Plugins/Android/"); string dstRoot; dstRoot = "Assets/Plugins/Android/"; string srcPath; srcPath = srcRoot + "." + PlatformUtil.ActivePlatform.ToString() + "/"; string dstPath; dstPath = dstRoot + "." + PlatformUtil.ActivePlatform.ToString() + "/"; Debug.Log("Copying AndroidManifest.xml from " + srcPath + " to " + dstPath); if (Directory.Exists(dstPath) && Directory.Exists(dstPath)) { File.Copy(srcPath + "AndroidManifest.xml", dstPath + "AndroidManifest.xml", true); } } catch (System.Exception e) { Debug.LogException(e); } } }
public static void OnPreprocess(IBuildProcessor processor) { ProductInfo info; info = PlatformUtil.GetSettings <ProductInfo>(); if (info) { ComputeAnalyticsNameOverride(info); } }
public static void OnBuildPreprocess(IBuildProcessor intstance) { PlayerSettings.iOS.appInBackgroundBehavior = iOSAppInBackgroundBehavior.Suspend; #if (SAGO_IOS_DEMO || SAGO_TVOS_DEMO) && !SAGO_DISABLE_SAGOBIZ throw new System.InvalidOperationException("Preprocessing error occured: SAGO_DISABLE_SAGOBIZ not defined. In order to build an iOS / tvOS demo, the SAGO_DISABLE_SAGOBIZ must be defined."); #endif #if (SAGO_IOS_DEMO || SAGO_TVOS_DEMO) && UNITY_5_3_OR_NEWER && UNITY_TVOS if (intstance is SagoBuildEditor.tvOS.tvOSBuildProcessor) { PlayerSettings.iOS.appInBackgroundBehavior = iOSAppInBackgroundBehavior.Exit; } #endif }
/// <summary> /// A helper method subclasses can use to implement the <see cref="Processor" /> logic. /// </summary> /// <param name="buildPath"> /// The path to the build directory. When running in the editor, the value /// will be an absolute path. When running in the cloud, the value may be /// relative or absolute (the Cloud Build documentation isn't clear). /// </param> public static void OnPostprocess(string buildPath) { if (BuildProcessor.Processor == null) { Debug.LogError(string.Format("Invalid operation: Processor does not exist: {0}", BuildProcessor.Processor)); return; } try { BuildProcessor.Processor.PostprocessBegin(buildPath); BuildProcessor.Processor.Postprocess(buildPath); OnBuildPostprocessAttribute.Invoke(BuildProcessor.Processor); BuildProcessor.Processor.PostprocessEnd(buildPath); } finally { BuildProcessor.Processor = null; } }
public static void PostprocessXcodeProject(IBuildProcessor processor) { iOSBuildProcessor ios; ios = processor as iOSBuildProcessor; if (ios == null) { return; } string pbxPath; pbxPath = Path.Combine(ios.XcodeProjectPath, "Unity-iPhone.xcodeproj/project.pbxproj"); PBXProject project; project = new PBXProject(); project.ReadFromFile(pbxPath); string externalNativeAssetsPath; externalNativeAssetsPath = Path.Combine(ios.ProjectPath, Path.Combine(SubmoduleMap.GetSubmodulePath(typeof(SagoLayout.SubmoduleInfo)), "Plugins/iOS/.Native")); string target; target = project.TargetGuidByName(PBXProject.GetUnityTargetName()); project.AddFileToBuild(target, project.AddFile( Path.Combine(externalNativeAssetsPath, "SLSafeArea.mm"), Path.Combine(XcodeGroupPath, "SLSafeArea.mm"), PBXSourceTree.Source )); // write xcode project project.WriteToFile(pbxPath); }
/// <summary> /// Initializes a new instance of the <see cref="DefaultExecuteStrategy" /> class. /// </summary> /// <param name="buildHistory">The build history tracker.</param> /// <param name="buildLog">The build log.</param> /// <param name="buildProcessor">The build processor.</param> public DefaultExecuteStrategy(IBuildHistory buildHistory, IBuildLog buildLog, IBuildProcessor buildProcessor) : base(buildHistory, buildLog, buildProcessor) { }
public static void Invoke(IBuildProcessor processor) { CallbackOrderAttribute.Invoke <OnBuildPostprocessAttribute>(new object[] { processor }); }
public static void OnBuildPostprocess(IBuildProcessor processor) { if (processor is iOSBuildProcessor) { iOSBuildProcessor ios; ios = processor as iOSBuildProcessor; string projectPath; projectPath = Path.Combine(ios.XcodeProjectPath, "Unity-iPhone.xcodeproj/project.pbxproj"); PBXProject project; project = new PBXProject(); project.ReadFromFile(projectPath); string submodulePath; submodulePath = SubmoduleMap.GetSubmodulePath(typeof(SagoApp.SubmoduleInfo)); string nativeAssetsPath; nativeAssetsPath = Path.Combine(ios.ProjectPath, Path.Combine(submodulePath, "Plugins/iOS/.Native")); string target; target = project.TargetGuidByName(PBXProject.GetUnityTargetName()); project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, "AudioSessionUtil.h"), Path.Combine("SagoApp", "AudioSessionUtil.h"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, "AudioSessionUtil.mm"), Path.Combine("SagoApp", "AudioSessionUtil.mm"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, "SAOnDemandResourceUtil.h"), Path.Combine("SagoApp", "SAOnDemandResourceUtil.h"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, "SAOnDemandResourceUtil.mm"), Path.Combine("SagoApp", "SAOnDemandResourceUtil.mm"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, "SAInstalledAppsHelper.h"), Path.Combine("SagoApp", "SAInstalledAppsHelper.h"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, "SAInstalledAppsHelper.mm"), Path.Combine("SagoApp", "SAInstalledAppsHelper.mm"), PBXSourceTree.Source )); // Open source third-party library for Unity for storing data in iOS keychain. project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, "UICKeyChainStore.h"), Path.Combine("SagoApp", "UICKeyChainStore.h"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, "UICKeyChainStore.m"), Path.Combine("SagoApp", "UICKeyChainStore.m"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, "SAKeychainStore.h"), Path.Combine("SagoApp", "SAKeychainStore.h"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, "SAKeychainStore.mm"), Path.Combine("SagoApp", "SAKeychainStore.mm"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, "UnityViewController+DeferSystemGestures.mm"), Path.Combine("SagoApp", "UnityViewController+DeferSystemGestures.mm"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, "SendEmailUtil.h"), Path.Combine("SagoApp", "SendEmailUtil.h"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, "SendEmailUtil.mm"), Path.Combine("SagoApp", "SendEmailUtil.mm"), PBXSourceTree.Source )); // Following section of code is to fix error caused when disposing Unity's OnDemandResourcesRequest // even though ODR download is incomplete. // First find Unity's original copy of OnDemandREsources.mm file and remove it. string onDemandResourcesFileGuid = project.FindFileGuidByProjectPath("Classes/Unity/OnDemandResources.mm"); project.RemoveFile(onDemandResourcesFileGuid); // Now add our updated implmentation of OnDemandResources.mm file. project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, "OnDemandResources.mm"), Path.Combine("Classes/Unity", "OnDemandResources.mm"), PBXSourceTree.Source )); // Adding odr_update_bug_fix.txt & odr_update_bug_fix_v2.txt file to Xcode project and marking // it with initial install tag to fix ODR update bug. // // Jira: https://sagosago.atlassian.net/browse/SW-168 #if ENABLE_IOS_ON_DEMAND_RESOURCES bool hasOdrAssetBundle = HasOnDemandResourcesAssetBundle; if (hasOdrAssetBundle) { // odr_update_bug_fix.txt string odrUpdateBugFixResTag = "odr_update_bug_fix"; string odrUpdateBugFixResFileName = "odr_update_bug_fix.txt"; string targetGuid = project.TargetGuidByName(PBXProject.GetUnityTargetName()); string odrUpdateBugFixResFileGuid = null; project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, odrUpdateBugFixResFileName), Path.Combine("SagoApp", odrUpdateBugFixResFileName), PBXSourceTree.Source )); odrUpdateBugFixResFileGuid = project.FindFileGuidByProjectPath(Path.Combine("SagoApp", odrUpdateBugFixResFileName)); project.AddAssetTagForFile(targetGuid, odrUpdateBugFixResFileGuid, odrUpdateBugFixResTag); project.AddAssetTagToDefaultInstall(targetGuid, odrUpdateBugFixResTag); // odr_update_bug_fix_v2.txt odrUpdateBugFixResTag = "odr_update_bug_fix_v2"; odrUpdateBugFixResFileName = "odr_update_bug_fix_v2.txt"; targetGuid = project.TargetGuidByName(PBXProject.GetUnityTargetName()); odrUpdateBugFixResFileGuid = null; project.AddFileToBuild(target, project.AddFile( Path.Combine(nativeAssetsPath, odrUpdateBugFixResFileName), Path.Combine("SagoApp", odrUpdateBugFixResFileName), PBXSourceTree.Source )); odrUpdateBugFixResFileGuid = project.FindFileGuidByProjectPath(Path.Combine("SagoApp", odrUpdateBugFixResFileName)); project.AddAssetTagForFile(targetGuid, odrUpdateBugFixResFileGuid, odrUpdateBugFixResTag); project.AddAssetTagToDefaultInstall(targetGuid, odrUpdateBugFixResTag); } #endif project.WriteToFile(projectPath); // There is a bug with Unity's XcodeAPI with how it adds resources to initial install tags. // It adds to "knownAssetTags" instead of "KnownAssetTags". // So we are actually modifying .pbxproj file by search and replace as a work around. #if ENABLE_IOS_ON_DEMAND_RESOURCES if (hasOdrAssetBundle) { string pbxProjFileText = File.ReadAllText(projectPath); if (pbxProjFileText.Contains("KnownAssetTags")) { throw new System.Exception(string.Format(@"Failed to search and replace 'knownAssetTags' with 'KnownAssetTags' in file {0}. Try merging existing 'KnownAssetTags' value instead." , projectPath)); } pbxProjFileText = pbxProjFileText.Replace("knownAssetTags", "KnownAssetTags"); File.WriteAllText(projectPath, pbxProjFileText); } #endif //Adding few permissions to Info.plist for iOS platform. // Get plist string plistPath = ios.XcodeProjectPath + "/Info.plist"; PlistDocument plist = new PlistDocument(); plist.ReadFromString(File.ReadAllText(plistPath)); // Get root PlistElementDict rootDict = plist.root; // Adding iOS permission string values for several permissions that our apps possibly need to Info.plist. rootDict.SetString("NSPhotoLibraryUsageDescription", "This app would like to save photos to your camera roll."); rootDict.SetString("NSCameraUsageDescription", "This activity requires secure access to your camera."); // Apple did not reject app submissions even though the following permissions have their values left empty, // so we are just going to leave them empty. rootDict.SetString("NSMicrophoneUsageDescription", ""); rootDict.SetString("NSMotionUsageDescription", ""); // Leaving this permission's string value empty as well. // This is a new permission for iOS 11. // Any addtional permissions that needs to be added, refer to: // https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html rootDict.SetString("NSPhotoLibraryAddUsageDescription", ""); // Write to file File.WriteAllText(plistPath, plist.WriteToString()); } }
public static void PostprocessXcodeProject(IBuildProcessor processor) { #if !SAGO_DISABLE_SAGOBIZ iOSBuildProcessor ios; ios = processor as iOSBuildProcessor; if (ios == null) { return; } string pbxPath; pbxPath = Path.Combine(ios.XcodeProjectPath, "Unity-iPhone.xcodeproj/project.pbxproj"); PBXProject project; project = new PBXProject(); project.ReadFromFile(pbxPath); string externalNativeAssetsPath; externalNativeAssetsPath = Path.Combine(ios.ProjectPath, Path.Combine(SubmoduleMap.GetSubmodulePath(typeof(SagoBiz.SubmoduleInfo)), "Plugins/iOS/.Native")); string target; target = project.TargetGuidByName(PBXProject.GetUnityTargetName()); project.AddFileToBuild(target, project.AddFile( Path.Combine(externalNativeAssetsPath, "SBNativeBindings.h"), Path.Combine(XcodeGroupPath, "SBNativeBindings.h"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(externalNativeAssetsPath, "SBNativeBindings.mm"), Path.Combine(XcodeGroupPath, "SBNativeBindings.mm"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(externalNativeAssetsPath, "SagoBiz.framework"), Path.Combine(XcodeGroupPath, "SagoBiz.framework"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(externalNativeAssetsPath, "SagoBiz.framework/Resources/SagoBiz.bundle"), Path.Combine(XcodeGroupPath, "SagoBiz.bundle"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(externalNativeAssetsPath, "SBStoreReviewController.h"), Path.Combine(XcodeGroupPath, "SBStoreReviewController.h"), PBXSourceTree.Source )); project.AddFileToBuild(target, project.AddFile( Path.Combine(externalNativeAssetsPath, "SBStoreReviewController.mm"), Path.Combine(XcodeGroupPath, "SBStoreReviewController.mm"), PBXSourceTree.Source )); // Read our AdjustConfig.plist template in externalNativeAssetsPath folder. AdjustOptions adjustOptions = SagoPlatform.PlatformUtil.GetSettings <AdjustOptions>(); if (adjustOptions != null) { Dictionary <string, object> adjConfigDict = (Dictionary <string, object>)Plist.readPlist(Path.Combine(externalNativeAssetsPath, "SBAdjust.plist")); adjConfigDict["AdjustToken"] = adjustOptions.AppToken; adjConfigDict["AdjustDebug"] = adjustOptions.IsDebug; adjConfigDict["AdjustLogLevel"] = adjustOptions.LogLevel; // Copy AdjustConfig.plist to iOS Xcode project path and add to Xcode project. Plist.writeXml(adjConfigDict, Path.Combine(ios.XcodeProjectPath, "SBAdjust.plist")); project.AddFileToBuild(target, project.AddFile( Path.Combine(ios.XcodeProjectPath, "SBAdjust.plist"), Path.Combine(XcodeGroupPath, "SBAdjust.plist"), PBXSourceTree.Source )); } project.UpdateBuildProperty(target, "HEADER_SEARCH_PATHS", new[] { string.Format("\"{0}\"/SagoBiz.framework/Headers", externalNativeAssetsPath) }, null); project.AddBuildProperty(target, "OTHER_LDFLAGS", "-licucore"); // Adjust runtime "unrecognized selector sent to instance" error fix. // Seems like an issue with static framework being added. project.AddBuildProperty(target, "OTHER_LDFLAGS", "-ObjC"); // Starting in Unity 5.x, ARC is enabled by default, but SBNativeBindings.mm // has non-ARC code, so we have to turn off arc for SBNativeBindings.mm if (BuildProcessor.UnityVersion.Major >= 5) { string file = project.FindFileGuidByProjectPath(Path.Combine(XcodeGroupPath, "SBNativeBindings.mm")); var flags = project.GetCompileFlagsForFile(target, file); flags.Add("-fno-objc-arc"); project.SetCompileFlagsForFile(target, file, flags); } // NOTE: Xcode splits the values for FRAMEWORK_SEARCH_PATHS on spaces, so if // a value contains spaces it needs to be quoted. However, AddBuildProperty // and SetBuildProperty will strip quotes from the value if it begins and ends // with a quote. To prevent the quotes from being stripped, use string.Format // with $(inherited) at the beginning instead of using separate calls to // AddBuildProperty. project.AddBuildProperty(target, "FRAMEWORK_SEARCH_PATHS", string.Format("\"{0}\"", externalNativeAssetsPath)); // write xcode project project.WriteToFile(pbxPath); #endif }
/// <summary> /// Initializes a new instance of the <see cref="DefaultExecuteStrategy" /> class. /// </summary> /// <param name="buildHistory">The build history tracker.</param> /// <param name="buildLog">The build log.</param> /// <param name="buildProcessor">The build processor.</param> public DefaultExecuteStrategy(IBuildHistory buildHistory, IBuildLog buildLog, IBuildProcessor buildProcessor) { _buildHistory = buildHistory ?? throw new ArgumentNullException(nameof(buildHistory)); Log = buildLog ?? throw new ArgumentNullException(nameof(buildLog)); _buildProcessor = buildProcessor ?? throw new ArgumentNullException(nameof(buildProcessor)); }