public override int GetHashCode() { int hash = 1; if (RegistrationId.Length != 0) { hash ^= RegistrationId.GetHashCode(); } if (BundleIdentifier.Length != 0) { hash ^= BundleIdentifier.GetHashCode(); } if (PayloadByteSize != 0) { hash ^= PayloadByteSize.GetHashCode(); } return(hash); }
PString MergeEntitlementString(PString pstr, MobileProvision profile, bool expandWildcards) { string TeamIdentifierPrefix; string AppIdentifierPrefix; if (string.IsNullOrEmpty(pstr.Value)) { return((PString)pstr.Clone()); } if (profile == null) { if (!warnedTeamIdentifierPrefix && pstr.Value.Contains("$(TeamIdentifierPrefix)")) { Log.LogWarning(null, null, null, Entitlements, 0, 0, 0, 0, MSBStrings.W0108); warnedTeamIdentifierPrefix = true; } if (!warnedAppIdentifierPrefix && pstr.Value.Contains("$(AppIdentifierPrefix)")) { Log.LogWarning(null, null, null, Entitlements, 0, 0, 0, 0, MSBStrings.W0109); warnedAppIdentifierPrefix = true; } } if (profile != null && profile.ApplicationIdentifierPrefix.Count > 0) { AppIdentifierPrefix = profile.ApplicationIdentifierPrefix[0] + "."; } else { AppIdentifierPrefix = string.Empty; } if (profile != null && profile.TeamIdentifierPrefix.Count > 0) { TeamIdentifierPrefix = profile.TeamIdentifierPrefix[0] + "."; } else { TeamIdentifierPrefix = AppIdentifierPrefix; } var customTags = new Dictionary <string, string> (StringComparer.OrdinalIgnoreCase) { { "TeamIdentifierPrefix", TeamIdentifierPrefix }, { "AppIdentifierPrefix", AppIdentifierPrefix }, { "CFBundleIdentifier", BundleIdentifier }, }; var expanded = StringParserService.Parse(pstr.Value, customTags); if (expandWildcards && expanded.IndexOf('*') != -1) { int asterisk = expanded.IndexOf('*'); string prefix; if (expanded.StartsWith(TeamIdentifierPrefix, StringComparison.Ordinal)) { prefix = TeamIdentifierPrefix; } else if (expanded.StartsWith(AppIdentifierPrefix, StringComparison.Ordinal)) { prefix = AppIdentifierPrefix; } else { prefix = string.Empty; } var baseBundleIdentifier = expanded.Substring(prefix.Length, asterisk - prefix.Length); if (!BundleIdentifier.StartsWith(baseBundleIdentifier, StringComparison.Ordinal)) { expanded = expanded.Replace("*", BundleIdentifier); } else { expanded = prefix + BundleIdentifier; } } return(new PString(expanded)); }
void CreateWatchOSExtensionProject() { var csproj = inputProject; var suffix = Suffix + "-extension"; // Remove unused configurations csproj.DeleteConfiguration("iPhone", "Release-bitcode"); csproj.DeleteConfiguration("iPhone", "Release64"); csproj.DeleteConfiguration("iPhone", "Debug64"); csproj.FixArchitectures("i386", "ARMv7k", "iPhone", "Release32"); csproj.FixArchitectures("i386", "ARMv7k", "iPhone", "Debug32"); // add Release64_32 and set the correct architecture csproj.CloneConfiguration("iPhone", "Release", "Release64_32"); csproj.FixArchitectures("i386", "ARM64_32", "iPhone", "Release64_32"); // add Debug64_32 and set the correct architecture csproj.CloneConfiguration("iPhone", "Debug", "Debug64_32"); csproj.FixArchitectures("i386", "ARM64_32", "iPhone", "Debug64_32"); csproj.FixArchitectures(SimulatorArchitectures, DeviceArchitectures, "iPhoneSimulator", "Debug"); csproj.FixArchitectures(SimulatorArchitectures, DeviceArchitectures, "iPhoneSimulator", "Release"); csproj.FixArchitectures(SimulatorArchitectures, DeviceArchitectures, "iPhone", "Debug"); csproj.FixArchitectures(SimulatorArchitectures, DeviceArchitectures, "iPhone", "Release"); csproj.SetProjectTypeGuids("{1E2E965C-F6D2-49ED-B86E-418A60C69EEF};" + LanguageGuid); csproj.SetOutputPath("bin\\$(Platform)\\$(Configuration)" + suffix); csproj.SetIntermediateOutputPath("obj\\$(Platform)\\$(Configuration)" + suffix); csproj.RemoveTargetFrameworkIdentifier(); csproj.SetPlatformAssembly("Xamarin.WatchOS"); csproj.SetImport(IsFSharp ? "$(MSBuildExtensionsPath)\\Xamarin\\WatchOS\\Xamarin.WatchOS.AppExtension.FSharp.targets" : "$(MSBuildExtensionsPath)\\Xamarin\\WatchOS\\Xamarin.WatchOS.AppExtension.CSharp.targets"); csproj.FixProjectReferences("-watchos"); csproj.FixInfoPListInclude(suffix); csproj.SetOutputType("Library"); csproj.AddAdditionalDefines("BITCODE", "iPhone", "Release"); csproj.AddAdditionalDefines("XAMCORE_2_0;XAMCORE_3_0;FEATURE_NO_BSD_SOCKETS;MONOTOUCH_WATCH;"); csproj.RemoveReferences("OpenTK-1.0"); var ext = IsFSharp ? "fs" : "cs"; csproj.AddCompileInclude("InterfaceController." + ext, Path.Combine(Harness.WatchOSExtensionTemplate, "InterfaceController." + ext)); csproj.SetExtraLinkerDefs("extra-linker-defs" + ExtraLinkerDefsSuffix + ".xml"); csproj.SetMtouchUseBitcode(true, "iPhone", "Release"); csproj.SetMtouchUseLlvm(true, "iPhone", "Release"); if (MonoNativeInfo != null) { csproj.AddAdditionalDefines("MONO_NATIVE_WATCH"); MonoNativeHelper.AddProjectDefines(csproj, MonoNativeInfo.Flavor); MonoNativeHelper.RemoveSymlinkMode(csproj); } // Not linking a watch extensions requires passing -Os to the native compiler. // https://github.com/mono/mono/issues/9867 var configurations = new string [] { "Debug", "Debug32", "Debug64_32", "Release", "Release32", "Release64_32" }; foreach (var c in configurations) { var flags = "-fembed-bitcode-marker"; if (csproj.GetMtouchLink("iPhone", c) == "None") { flags += " -Os"; } csproj.AddExtraMtouchArgs($"--gcc_flags='{flags}'", "iPhone", c); } Harness.Save(csproj, WatchOSExtensionProjectPath); WatchOSExtensionGuid = csproj.GetProjectGuid(); XmlDocument info_plist = new XmlDocument(); var target_info_plist = Path.Combine(TargetDirectory, $"Info{Suffix}-extension.plist"); info_plist.LoadWithoutNetworkAccess(Path.Combine(TargetDirectory, "Info.plist")); BundleIdentifier = info_plist.GetCFBundleIdentifier() + "_watch"; if (BundleIdentifier.Length >= 58) { BundleIdentifier = BundleIdentifier.Substring(0, 57); // If the main app's bundle id is 58 characters (or sometimes more), then the watch extension crashes at launch. radar #29847128. } info_plist.SetCFBundleIdentifier(BundleIdentifier + ".watchkitapp.watchkitextension"); info_plist.SetMinimumOSVersion(GetMinimumOSVersion("2.0")); info_plist.SetUIDeviceFamily(4); info_plist.AddPListStringValue("RemoteInterfacePrincipleClass", "InterfaceController"); info_plist.AddPListKeyValuePair("NSExtension", "dict", string.Format( @" <key>NSExtensionAttributes</key> <dict> <key>WKAppBundleIdentifier</key> <string>{0}.watchkitapp</string> </dict> <key>NSExtensionPointIdentifier</key> <string>com.apple.watchkit</string> ", BundleIdentifier)); if (!info_plist.ContainsKey("NSAppTransportSecurity")) { info_plist.AddPListKeyValuePair("NSAppTransportSecurity", "dict", @" <key>NSAllowsArbitraryLoads</key> <true/> " ); } Harness.Save(info_plist, target_info_plist); }
public static bool GeneratePList(string ProjectDirectory, bool bIsUE4Game, string GameName, string ProjectName, string InEngineDir, string AppDirectory) { // generate the Info.plist for future use string BuildDirectory = ProjectDirectory + "/Build/IOS"; bool bSkipDefaultPNGs = false; string IntermediateDirectory = (bIsUE4Game ? InEngineDir : ProjectDirectory) + "/Intermediate/IOS"; string PListFile = IntermediateDirectory + "/" + GameName + "-Info.plist"; VersionUtilities.BuildDirectory = BuildDirectory; VersionUtilities.GameName = GameName; // read the old file string OldPListData = File.Exists(PListFile) ? File.ReadAllText(PListFile) : ""; // determine if there is a launch.xib string LaunchXib = InEngineDir + "/Build/IOS/Resources/Interface/LaunchScreen.xib"; if (File.Exists(BuildDirectory + "/Resources/Interface/LaunchScreen.xib")) { LaunchXib = BuildDirectory + "/Resources/Interface/LaunchScreen.xib"; } // get the settings from the ini file // plist replacements ConfigCacheIni Ini = new ConfigCacheIni(UnrealTargetPlatform.IOS, "Engine", UnrealBuildTool.GetUProjectPath()); // orientations string SupportedOrientations = ""; bool bSupported = true; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsPortraitOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationPortrait</string>\n" : ""; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsUpsideDownOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n" : ""; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsLandscapeLeftOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n" : ""; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsLandscapeRightOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n" : ""; // bundle display name string BundleDisplayName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleDisplayName", out BundleDisplayName); // bundle identifier string BundleIdentifier; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier", out BundleIdentifier); // bundle name string BundleName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleName", out BundleName); // short version string string BundleShortVersion; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "VersionInfo", out BundleShortVersion); // required capabilities string RequiredCaps = "\t\t<string>armv7</string>\n"; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsOpenGLES2", out bSupported); RequiredCaps += bSupported ? "\t\t<string>opengles-2</string>\n" : ""; if (!bSupported) { Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsMetal", out bSupported); RequiredCaps += bSupported ? "\t\t<string>metal</string>\n" : ""; } // minimum iOS version string MinVersion; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion", out MinVersion)) { switch (MinVersion) { case "IOS_61": MinVersion = "6.1"; break; case "IOS_7": MinVersion = "7.0"; break; case "IOS_8": MinVersion = "8.0"; break; } } else { MinVersion = "6.1"; } // Get Facebook Support details bool bEnableFacebookSupport = true; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bEnableFacebookSupport", out bEnableFacebookSupport); // Write the Facebook App ID if we need it. string FacebookAppID = ""; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "FacebookAppID", out FacebookAppID); bEnableFacebookSupport = bEnableFacebookSupport && !string.IsNullOrWhiteSpace(FacebookAppID); // extra plist data string ExtraData = ""; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalPlistData", out ExtraData); // generate the plist file StringBuilder Text = new StringBuilder(); Text.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); Text.AppendLine("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); Text.AppendLine("<plist version=\"1.0\">"); Text.AppendLine("<dict>"); Text.AppendLine("\t<key>CFBundleURLTypes</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>CFBundleURLName</key>"); Text.AppendLine("\t\t\t<string>com.Epic.Unreal</string>"); Text.AppendLine("\t\t\t<key>CFBundleURLSchemes</key>"); Text.AppendLine("\t\t\t<array>"); Text.AppendLine(string.Format("\t\t\t\t<string>{0}</string>", bIsUE4Game ? "UE4Game" : GameName)); if (bEnableFacebookSupport) { // This is needed for facebook login to redirect back to the app after completion. Text.AppendLine(string.Format("\t\t\t\t<string>fb{0}</string>", FacebookAppID)); } Text.AppendLine("\t\t\t</array>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>CFBundleDevelopmentRegion</key>"); Text.AppendLine("\t<string>English</string>"); Text.AppendLine("\t<key>CFBundleDisplayName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleDisplayName.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""))); Text.AppendLine("\t<key>CFBundleExecutable</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", bIsUE4Game ? "UE4Game" : GameName)); Text.AppendLine("\t<key>CFBundleIdentifier</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleIdentifier.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""))); Text.AppendLine("\t<key>CFBundleInfoDictionaryVersion</key>"); Text.AppendLine("\t<string>6.0</string>"); Text.AppendLine("\t<key>CFBundleName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleName.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""))); Text.AppendLine("\t<key>CFBundlePackageType</key>"); Text.AppendLine("\t<string>APPL</string>"); Text.AppendLine("\t<key>CFBundleSignature</key>"); Text.AppendLine("\t<string>????</string>"); Text.AppendLine("\t<key>CFBundleVersion</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", VersionUtilities.UpdateBundleVersion(OldPListData))); Text.AppendLine("\t<key>CFBundleShortVersionString</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleShortVersion)); Text.AppendLine("\t<key>LSRequiresIPhoneOS</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIStatusBarHidden</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIViewControllerBasedStatusBarAppearance</key>"); Text.AppendLine("\t<false/>"); Text.AppendLine("\t<key>UISupportedInterfaceOrientations</key>"); Text.AppendLine("\t<array>"); foreach (string Line in SupportedOrientations.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine(Line); } } Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>UIRequiredDeviceCapabilities</key>"); Text.AppendLine("\t<array>"); foreach (string Line in RequiredCaps.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine(Line); } } Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>CFBundleIcons</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>CFBundleIconFiles</key>"); Text.AppendLine("\t\t\t<array>"); Text.AppendLine("\t\t\t\t<string>Icon29.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon40.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon57.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t</array>"); Text.AppendLine("\t\t\t<key>UIPrerenderedIcon</key>"); Text.AppendLine("\t\t\t<true/>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</dict>"); Text.AppendLine("\t<key>CFBundleIcons~ipad</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>CFBundleIconFiles</key>"); Text.AppendLine("\t\t\t<array>"); Text.AppendLine("\t\t\t\t<string>Icon29.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon40.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon50.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon72.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon76.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t</array>"); Text.AppendLine("\t\t\t<key>UIPrerenderedIcon</key>"); Text.AppendLine("\t\t\t<true/>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</dict>"); if (File.Exists(LaunchXib)) { // TODO: compile the xib via remote tool Text.AppendLine("\t<key>UILaunchStoryboardName</key>"); Text.AppendLine("\t<string>LaunchScreen</string>"); bSkipDefaultPNGs = true; } else { // this is a temp way to inject the iphone 6 images without needing to upgrade everyone's plist // eventually we want to generate this based on what the user has set in the project settings string[] IPhoneConfigs = { "Default-IPhone6", "Landscape", "{375, 667}", "Default-IPhone6", "Portrait", "{375, 667}", "Default-IPhone6Plus-Landscape", "Landscape", "{414, 736}", "Default-IPhone6Plus-Portrait", "Portrait", "{414, 736}", "Default", "Landscape", "{320, 480}", "Default", "Portrait", "{320, 480}", "Default-568h", "Landscape", "{320, 568}", "Default-568h", "Portrait", "{320, 568}", }; Text.AppendLine("\t<key>UILaunchImages~iphone</key>"); Text.AppendLine("\t<array>"); for (int ConfigIndex = 0; ConfigIndex < IPhoneConfigs.Length; ConfigIndex += 3) { Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); Text.AppendLine("\t\t\t<string>8.0</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 0])); Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 1])); Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 2])); Text.AppendLine("\t\t</dict>"); } // close it out Text.AppendLine("\t</array>"); } Text.AppendLine("\t<key>UILaunchImages~ipad</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); Text.AppendLine("\t\t\t<string>7.0</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); Text.AppendLine("\t\t\t<string>Default-Landscape</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); Text.AppendLine("\t\t\t<string>Landscape</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); Text.AppendLine("\t\t\t<string>{768, 1024}</string>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); Text.AppendLine("\t\t\t<string>7.0</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); Text.AppendLine("\t\t\t<string>Default-Portrait</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); Text.AppendLine("\t\t\t<string>Portrait</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); Text.AppendLine("\t\t\t<string>{768, 1024}</string>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>CFBundleSupportedPlatforms</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<string>iPhoneOS</string>"); Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>MinimumOSVersion</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", MinVersion)); if (bEnableFacebookSupport) { Text.AppendLine("\t<key>FacebookAppID</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", FacebookAppID)); } if (!string.IsNullOrEmpty(ExtraData)) { ExtraData = ExtraData.Replace("\\n", "\n"); foreach (string Line in ExtraData.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine("\t" + Line); } } } Text.AppendLine("</dict>"); Text.AppendLine("</plist>"); // write the file out if (!Directory.Exists(IntermediateDirectory)) { Directory.CreateDirectory(IntermediateDirectory); } File.WriteAllText(PListFile, Text.ToString()); if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { if (!Directory.Exists(AppDirectory)) { Directory.CreateDirectory(AppDirectory); } File.WriteAllText(AppDirectory + "/Info.plist", Text.ToString()); } return(bSkipDefaultPNGs); }
public static bool GeneratePList(string ProjectDirectory, bool bIsUE4Game, string GameName, string ProjectName, string InEngineDir, string ExeName) { string IntermediateDirectory = (bIsUE4Game ? InEngineDir : ProjectDirectory) + "/Intermediate/Mac"; string DestPListFile = IntermediateDirectory + "/" + ExeName + "-Info.plist"; string SrcPListFile = (bIsUE4Game ? (InEngineDir + "Source/Programs/") : (ProjectDirectory + "/Source/")) + GameName + "/Resources/Mac/Info.plist"; if (!File.Exists(SrcPListFile)) { SrcPListFile = InEngineDir + "/Source/Runtime/Launch/Resources/Mac/Info.plist"; } string PListData = null; if (File.Exists(SrcPListFile)) { PListData = File.ReadAllText(SrcPListFile); } else { return(false); } // bundle identifier // plist replacements DirectoryReference DirRef = bIsUE4Game ? (!string.IsNullOrEmpty(UnrealBuildTool.GetRemoteIniPath()) ? new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()) : null) : new DirectoryReference(ProjectDirectory); ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirRef, UnrealTargetPlatform.IOS); string BundleIdentifier; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier", out BundleIdentifier); string BundleVersion = MacToolChain.LoadEngineDisplayVersion(); PListData = PListData.Replace("${EXECUTABLE_NAME}", ExeName).Replace("${APP_NAME}", BundleIdentifier.Replace("[PROJECT_NAME]", ProjectName).Replace("_", "")).Replace("${ICON_NAME}", GameName).Replace("${MACOSX_DEPLOYMENT_TARGET}", MacToolChain.Settings.MinMacOSVersion).Replace("${BUNDLE_VERSION}", BundleVersion); if (!Directory.Exists(IntermediateDirectory)) { Directory.CreateDirectory(IntermediateDirectory); } File.WriteAllText(DestPListFile, PListData); return(true); }
public static bool GenerateIOSPList(string ProjectDirectory, bool bIsUE4Game, string GameName, string ProjectName, string InEngineDir, string AppDirectory, UEDeployIOS InThis = null) { // generate the Info.plist for future use string BuildDirectory = ProjectDirectory + "/Build/IOS"; bool bSkipDefaultPNGs = false; string IntermediateDirectory = (bIsUE4Game ? InEngineDir : ProjectDirectory) + "/Intermediate/IOS"; string PListFile = IntermediateDirectory + "/" + GameName + "-Info.plist"; ProjectName = !String.IsNullOrEmpty(ProjectName) ? ProjectName : GameName; VersionUtilities.BuildDirectory = BuildDirectory; VersionUtilities.GameName = GameName; // read the old file string OldPListData = File.Exists(PListFile) ? File.ReadAllText(PListFile) : ""; // determine if there is a launch.xib string LaunchXib = InEngineDir + "/Build/IOS/Resources/Interface/LaunchScreen.xib"; if (File.Exists(BuildDirectory + "/Resources/Interface/LaunchScreen.xib")) { LaunchXib = BuildDirectory + "/Resources/Interface/LaunchScreen.xib"; } // get the settings from the ini file // plist replacements DirectoryReference DirRef = bIsUE4Game ? (!string.IsNullOrEmpty(UnrealBuildTool.GetRemoteIniPath()) ? new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()) : null) : new DirectoryReference(ProjectDirectory); ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.IOS, "Engine", DirRef); // orientations string SupportedOrientations = ""; bool bSupported = true; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsPortraitOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationPortrait</string>\n" : ""; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsUpsideDownOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n" : ""; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsLandscapeLeftOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n" : ""; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsLandscapeRightOrientation", out bSupported); SupportedOrientations += bSupported ? "\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n" : ""; // bundle display name string BundleDisplayName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleDisplayName", out BundleDisplayName); // bundle identifier string BundleIdentifier; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier", out BundleIdentifier); // bundle name string BundleName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleName", out BundleName); // disable https requirement bool bDisableHTTPS; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bDisableHTTPS", out bDisableHTTPS); // short version string string BundleShortVersion; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "VersionInfo", out BundleShortVersion); // required capabilities string RequiredCaps = ""; if (InThis != null) { // required capabilities RequiredCaps += InThis.IOSPlatformContext.GetRequiredCapabilities(); } Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsOpenGLES2", out bSupported); RequiredCaps += bSupported ? "\t\t<string>opengles-2</string>\n" : ""; if (!bSupported) { Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bSupportsMetal", out bSupported); RequiredCaps += bSupported ? "\t\t<string>metal</string>\n" : ""; } // minimum iOS version string MinVersion; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumiOSVersion", out MinVersion)) { switch (MinVersion) { case "IOS_61": Log.TraceWarning("IOS 6 is no longer supported in UE4 as 4.11"); MinVersion = "7.0"; break; case "IOS_7": MinVersion = "7.0"; break; case "IOS_8": MinVersion = "8.0"; break; case "IOS_9": MinVersion = "9.0"; break; } } else { MinVersion = "7.0"; } // Get Facebook Support details bool bEnableFacebookSupport = true; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bEnableFacebookSupport", out bEnableFacebookSupport); // Write the Facebook App ID if we need it. string FacebookAppID = ""; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "FacebookAppID", out FacebookAppID); bEnableFacebookSupport = bEnableFacebookSupport && !string.IsNullOrWhiteSpace(FacebookAppID); // Add remote-notifications as background mode bool bRemoteNotificationsSupported = false; Ini.GetBool("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "bEnableRemoteNotificationsSupport", out bRemoteNotificationsSupported); // extra plist data string ExtraData = ""; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalPlistData", out ExtraData); // generate the plist file StringBuilder Text = new StringBuilder(); Text.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); Text.AppendLine("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); Text.AppendLine("<plist version=\"1.0\">"); Text.AppendLine("<dict>"); Text.AppendLine("\t<key>CFBundleURLTypes</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>CFBundleURLName</key>"); Text.AppendLine("\t\t\t<string>com.Epic.Unreal</string>"); Text.AppendLine("\t\t\t<key>CFBundleURLSchemes</key>"); Text.AppendLine("\t\t\t<array>"); Text.AppendLine(string.Format("\t\t\t\t<string>{0}</string>", bIsUE4Game ? "UE4Game" : GameName)); if (bEnableFacebookSupport) { // This is needed for facebook login to redirect back to the app after completion. Text.AppendLine(string.Format("\t\t\t\t<string>fb{0}</string>", FacebookAppID)); } Text.AppendLine("\t\t\t</array>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>CFBundleDevelopmentRegion</key>"); Text.AppendLine("\t<string>English</string>"); Text.AppendLine("\t<key>CFBundleDisplayName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", EncodeBundleName(BundleDisplayName, ProjectName))); Text.AppendLine("\t<key>CFBundleExecutable</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", bIsUE4Game ? "UE4Game" : GameName)); Text.AppendLine("\t<key>CFBundleIdentifier</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleIdentifier.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""))); Text.AppendLine("\t<key>CFBundleInfoDictionaryVersion</key>"); Text.AppendLine("\t<string>6.0</string>"); Text.AppendLine("\t<key>CFBundleName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", EncodeBundleName(BundleName, ProjectName))); Text.AppendLine("\t<key>CFBundlePackageType</key>"); Text.AppendLine("\t<string>APPL</string>"); Text.AppendLine("\t<key>CFBundleSignature</key>"); Text.AppendLine("\t<string>????</string>"); Text.AppendLine("\t<key>CFBundleVersion</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", VersionUtilities.UpdateBundleVersion(OldPListData))); Text.AppendLine("\t<key>CFBundleShortVersionString</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleShortVersion)); Text.AppendLine("\t<key>LSRequiresIPhoneOS</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIStatusBarHidden</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIRequiresFullScreen</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIViewControllerBasedStatusBarAppearance</key>"); Text.AppendLine("\t<false/>"); Text.AppendLine("\t<key>UISupportedInterfaceOrientations</key>"); Text.AppendLine("\t<array>"); foreach (string Line in SupportedOrientations.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine(Line); } } Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>UIRequiredDeviceCapabilities</key>"); Text.AppendLine("\t<array>"); foreach (string Line in RequiredCaps.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine(Line); } } Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>CFBundleIcons</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>CFBundleIconFiles</key>"); Text.AppendLine("\t\t\t<array>"); Text.AppendLine("\t\t\t\t<string>Icon29.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon40.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon57.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t</array>"); Text.AppendLine("\t\t\t<key>UIPrerenderedIcon</key>"); Text.AppendLine("\t\t\t<true/>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</dict>"); Text.AppendLine("\t<key>CFBundleIcons~ipad</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>CFBundleIconFiles</key>"); Text.AppendLine("\t\t\t<array>"); Text.AppendLine("\t\t\t\t<string>Icon29.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon40.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon50.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon72.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>Icon76.png</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); Text.AppendLine("\t\t\t</array>"); Text.AppendLine("\t\t\t<key>UIPrerenderedIcon</key>"); Text.AppendLine("\t\t\t<true/>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</dict>"); if (File.Exists(LaunchXib)) { // TODO: compile the xib via remote tool Text.AppendLine("\t<key>UILaunchStoryboardName</key>"); Text.AppendLine("\t<string>LaunchScreen</string>"); bSkipDefaultPNGs = true; } else { // this is a temp way to inject the iphone 6 images without needing to upgrade everyone's plist // eventually we want to generate this based on what the user has set in the project settings string[] IPhoneConfigs = { "Default-IPhone6-Landscape", "Landscape", "{375, 667}", "8.0", "Default-IPhone6", "Portrait", "{375, 667}", "8.0", "Default-IPhone6Plus-Landscape", "Landscape", "{414, 736}", "8.0", "Default-IPhone6Plus-Portrait", "Portrait", "{414, 736}", "8.0", "Default", "Landscape", "{320, 480}", "7.0", "Default", "Portrait", "{320, 480}", "7.0", "Default-568h", "Landscape", "{320, 568}", "7.0", "Default-568h", "Portrait", "{320, 568}", "7.0", }; Text.AppendLine("\t<key>UILaunchImages~iphone</key>"); Text.AppendLine("\t<array>"); for (int ConfigIndex = 0; ConfigIndex < IPhoneConfigs.Length; ConfigIndex += 4) { Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 3])); Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 0])); Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 1])); Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 2])); Text.AppendLine("\t\t</dict>"); } // close it out Text.AppendLine("\t</array>"); // this is a temp way to inject the iPad Pro without needing to upgrade everyone's plist // eventually we want to generate this based on what the user has set in the project settings string[] IPadConfigs = { "Default-Landscape", "Landscape", "{768, 1024}", "7.0", "Default-Portrait", "Portrait", "{768, 1024}", "7.0", "Default-Landscape-1336", "Landscape", "{1024, 1366}", "9.0", "Default-Portrait-1336", "Portrait", "{1024, 1366}", "9.0", }; Text.AppendLine("\t<key>UILaunchImages~ipad</key>"); Text.AppendLine("\t<array>"); for (int ConfigIndex = 0; ConfigIndex < IPadConfigs.Length; ConfigIndex += 4) { Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPadConfigs[ConfigIndex + 3])); Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPadConfigs[ConfigIndex + 0])); Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPadConfigs[ConfigIndex + 1])); Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPadConfigs[ConfigIndex + 2])); Text.AppendLine("\t\t</dict>"); } Text.AppendLine("\t</array>"); } Text.AppendLine("\t<key>CFBundleSupportedPlatforms</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<string>iPhoneOS</string>"); Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>MinimumOSVersion</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", MinVersion)); // disable exempt encryption Text.AppendLine("\t<key>ITSAppUsesNonExemptEncryption</key>"); Text.AppendLine("\t<false/>"); // disable HTTPS requirement if (bDisableHTTPS) { Text.AppendLine("\t<key>NSAppTransportSecurity</key>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>NSAllowsArbitraryLoads</key><true/>"); Text.AppendLine("\t\t</dict>"); } if (bEnableFacebookSupport) { Text.AppendLine("\t<key>FacebookAppID</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", FacebookAppID)); } if (!string.IsNullOrEmpty(ExtraData)) { ExtraData = ExtraData.Replace("\\n", "\n"); foreach (string Line in ExtraData.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine("\t" + Line); } } } // Add remote-notifications as background mode if (bRemoteNotificationsSupported) { Text.AppendLine("\t<key>UIBackgroundModes</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<string>remote-notification</string>"); Text.AppendLine("\t</array>"); } Text.AppendLine("</dict>"); Text.AppendLine("</plist>"); // Create the intermediate directory if needed if (!Directory.Exists(IntermediateDirectory)) { Directory.CreateDirectory(IntermediateDirectory); } if (InThis != null && InThis.UPL != null) { // Allow UPL to modify the plist here XDocument XDoc; try { XDoc = XDocument.Parse(Text.ToString()); } catch (Exception e) { throw new BuildException("plist is invalid {0}\n{1}", e, Text.ToString()); } XDoc.DocumentType.InternalSubset = ""; InThis.UPL.ProcessPluginNode("None", "iosPListUpdates", "", ref XDoc); string result = XDoc.Declaration.ToString() + "\n" + XDoc.ToString().Replace("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"[]>", "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); File.WriteAllText(PListFile, result); } else { File.WriteAllText(PListFile, Text.ToString()); } if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { if (!Directory.Exists(AppDirectory)) { Directory.CreateDirectory(AppDirectory); } File.WriteAllText(AppDirectory + "/Info.plist", Text.ToString()); } return(bSkipDefaultPNGs); }
public static bool GenerateTVOSPList(string ProjectDirectory, bool bIsUE4Game, string GameName, bool bIsClient, string ProjectName, string InEngineDir, string AppDirectory, UnrealPluginLanguage UPL, string BundleID) { // @todo tvos: THIS! // generate the Info.plist for future use string BuildDirectory = ProjectDirectory + "/Build/TVOS"; bool bSkipDefaultPNGs = false; string IntermediateDirectory = (bIsUE4Game ? InEngineDir : ProjectDirectory) + "/Intermediate/TVOS"; string PListFile = IntermediateDirectory + "/" + GameName + "-Info.plist"; // @todo tvos: This is really nasty - both IOS and TVOS are setting static vars VersionUtilities.BuildDirectory = BuildDirectory; VersionUtilities.GameName = GameName; // read the old file string OldPListData = File.Exists(PListFile) ? File.ReadAllText(PListFile) : ""; // determine if there is a launch.xib //string LaunchXib = InEngineDir + "/Build/IOS/Resources/Interface/LaunchScreen.xib"; //if (File.Exists(BuildDirectory + "/Resources/Interface/LaunchScreen.xib")) //{ // LaunchXib = BuildDirectory + "/Resources/Interface/LaunchScreen.xib"; //} // get the settings from the ini file // plist replacements // @todo tvos: Are we going to make TVOS specific .ini files? DirectoryReference DirRef = bIsUE4Game ? (!string.IsNullOrEmpty(UnrealBuildTool.GetRemoteIniPath()) ? new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()) : null) : new DirectoryReference(ProjectDirectory); ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirRef, UnrealTargetPlatform.IOS); // bundle display name string BundleDisplayName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleDisplayName", out BundleDisplayName); // bundle identifier string BundleIdentifier; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier", out BundleIdentifier); if (!string.IsNullOrEmpty(BundleID)) { BundleIdentifier = BundleID; } // bundle name string BundleName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleName", out BundleName); // short version string string BundleShortVersion; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "VersionInfo", out BundleShortVersion); // required capabilities string RequiredCaps = "\t\t<string>arm64</string>\n"; // minimum iOS version string MinVersion; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumTVOSVersion", out MinVersion)) { switch (MinVersion) { case "TVOS_9": MinVersion = "9.0"; break; } } else { MinVersion = "9.0"; } // extra plist data string ExtraData = ""; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalPlistData", out ExtraData); // create the final display name, including converting all entities for XML use string FinalDisplayName = BundleDisplayName.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""); FinalDisplayName = FinalDisplayName.Replace("&", "&"); FinalDisplayName = FinalDisplayName.Replace("\"", """); FinalDisplayName = FinalDisplayName.Replace("\'", "'"); FinalDisplayName = FinalDisplayName.Replace("<", "<"); FinalDisplayName = FinalDisplayName.Replace(">", ">"); // generate the plist file StringBuilder Text = new StringBuilder(); Text.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); Text.AppendLine("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); Text.AppendLine("<plist version=\"1.0\">"); Text.AppendLine("<dict>"); Text.AppendLine("\t<key>CFBundleDevelopmentRegion</key>"); Text.AppendLine("\t<string>en</string>"); Text.AppendLine("\t<key>CFBundleDisplayName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", EncodeBundleName(BundleDisplayName, ProjectName))); Text.AppendLine("\t<key>CFBundleExecutable</key>"); string BundleExecutable = bIsUE4Game ? (bIsClient ? "UE4Client" : "UE4Game") : (bIsClient ? GameName + "Client" : GameName); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleExecutable)); Text.AppendLine("\t<key>CFBundleIdentifier</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleIdentifier.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""))); Text.AppendLine("\t<key>CFBundleInfoDictionaryVersion</key>"); Text.AppendLine("\t<string>6.0</string>"); Text.AppendLine("\t<key>CFBundleName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", EncodeBundleName(BundleName, ProjectName))); Text.AppendLine("\t<key>CFBundlePackageType</key>"); Text.AppendLine("\t<string>APPL</string>"); Text.AppendLine("\t<key>CFBundleSignature</key>"); Text.AppendLine("\t<string>????</string>"); Text.AppendLine("\t<key>CFBundleVersion</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", VersionUtilities.UpdateBundleVersion(OldPListData, InEngineDir))); Text.AppendLine("\t<key>CFBundleShortVersionString</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleShortVersion)); Text.AppendLine("\t<key>LSRequiresIPhoneOS</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIRequiredDeviceCapabilities</key>"); Text.AppendLine("\t<array>"); foreach (string Line in RequiredCaps.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine(Line); } } Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>TVTopShelfImage</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>TVTopShelfPrimaryImage</key>"); Text.AppendLine("\t\t<string>Top Shelf Image</string>"); Text.AppendLine("\t\t<key>TVTopShelfPrimaryImageWide</key>"); Text.AppendLine("\t\t<string>Top Shelf Image Wide</string>"); Text.AppendLine("\t</dict>"); Text.AppendLine("\t<key>UILaunchImages</key>"); Text.AppendLine("\t<array>"); Text.AppendLine("\t\t<dict>"); Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); Text.AppendLine("\t\t\t<string>{1920, 1080}</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); Text.AppendLine("\t\t\t<string>Launch Image</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); Text.AppendLine("\t\t\t<string>9.0</string>"); Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); Text.AppendLine("\t\t\t<string>Landscape</string>"); Text.AppendLine("\t\t</dict>"); Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>CFBundleIcons</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); Text.AppendLine("\t\t<string>App Icon</string>"); Text.AppendLine("\t</dict>"); /* Text.AppendLine("\t<key>CFBundleIcons</key>"); * Text.AppendLine("\t<dict>"); * Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>CFBundleIconFiles</key>"); * Text.AppendLine("\t\t\t<array>"); * Text.AppendLine("\t\t\t\t<string>Icon29.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon40.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon57.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t</array>"); * Text.AppendLine("\t\t\t<key>UIPrerenderedIcon</key>"); * Text.AppendLine("\t\t\t<true/>"); * Text.AppendLine("\t\t</dict>"); * Text.AppendLine("\t</dict>"); * Text.AppendLine("\t<key>CFBundleIcons~ipad</key>"); * Text.AppendLine("\t<dict>"); * Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>CFBundleIconFiles</key>"); * Text.AppendLine("\t\t\t<array>"); * Text.AppendLine("\t\t\t\t<string>Icon29.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon40.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon50.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon72.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon76.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t</array>"); * Text.AppendLine("\t\t\t<key>UIPrerenderedIcon</key>"); * Text.AppendLine("\t\t\t<true/>"); * Text.AppendLine("\t\t</dict>"); * Text.AppendLine("\t</dict>"); * if (File.Exists(LaunchXib)) * { * // TODO: compile the xib via remote tool * Text.AppendLine("\t<key>UILaunchStoryboardName</key>"); * Text.AppendLine("\t<string>LaunchScreen</string>"); * bSkipDefaultPNGs = true; * } * else * { * // this is a temp way to inject the iphone 6 images without needing to upgrade everyone's plist * // eventually we want to generate this based on what the user has set in the project settings * string[] IPhoneConfigs = * { * "Default-IPhone6", "Landscape", "{375, 667}", * "Default-IPhone6", "Portrait", "{375, 667}", * "Default-IPhone6Plus-Landscape", "Landscape", "{414, 736}", * "Default-IPhone6Plus-Portrait", "Portrait", "{414, 736}", * "Default", "Landscape", "{320, 480}", * "Default", "Portrait", "{320, 480}", * "Default-568h", "Landscape", "{320, 568}", * "Default-568h", "Portrait", "{320, 568}", * }; * * Text.AppendLine("\t<key>UILaunchImages~iphone</key>"); * Text.AppendLine("\t<array>"); * for (int ConfigIndex = 0; ConfigIndex < IPhoneConfigs.Length; ConfigIndex += 3) * { * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); * Text.AppendLine("\t\t\t<string>8.0</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); * Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 0])); * Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); * Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 1])); * Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); * Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 2])); * Text.AppendLine("\t\t</dict>"); * } * * // close it out * Text.AppendLine("\t</array>"); * } * Text.AppendLine("\t<key>UILaunchImages~ipad</key>"); * Text.AppendLine("\t<array>"); * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); * Text.AppendLine("\t\t\t<string>7.0</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); * Text.AppendLine("\t\t\t<string>Default-Landscape</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); * Text.AppendLine("\t\t\t<string>Landscape</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); * Text.AppendLine("\t\t\t<string>{768, 1024}</string>"); * Text.AppendLine("\t\t</dict>"); * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); * Text.AppendLine("\t\t\t<string>7.0</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); * Text.AppendLine("\t\t\t<string>Default-Portrait</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); * Text.AppendLine("\t\t\t<string>Portrait</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); * Text.AppendLine("\t\t\t<string>{768, 1024}</string>"); * Text.AppendLine("\t\t</dict>"); * Text.AppendLine("\t</array>"); * Text.AppendLine("\t<key>CFBundleSupportedPlatforms</key>"); * Text.AppendLine("\t<array>"); * Text.AppendLine("\t\t<string>iPhoneOS</string>"); * Text.AppendLine("\t</array>"); * Text.AppendLine("\t<key>MinimumOSVersion</key>"); * Text.AppendLine(string.Format("\t<string>{0}</string>", MinVersion)); * if (!string.IsNullOrEmpty(ExtraData)) * { * ExtraData = ExtraData.Replace("\\n", "\n"); * foreach (string Line in ExtraData.Split("\r\n".ToCharArray())) * { * if (!string.IsNullOrWhiteSpace(Line)) * { * Text.AppendLine("\t" + Line); * } * } * }*/ // write the iCloud container identifier, if present in the old file if (!string.IsNullOrEmpty(OldPListData)) { int index = OldPListData.IndexOf("ICloudContainerIdentifier"); if (index > 0) { index = OldPListData.IndexOf("<string>", index) + 8; int length = OldPListData.IndexOf("</string>", index) - index; string ICloudContainerIdentifier = OldPListData.Substring(index, length); Text.AppendLine("\t<key>ICloudContainerIdentifier</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", ICloudContainerIdentifier)); } } Text.AppendLine("</dict>"); Text.AppendLine("</plist>"); // Create the intermediate directory if needed if (!Directory.Exists(IntermediateDirectory)) { Directory.CreateDirectory(IntermediateDirectory); } if (UPL != null) { // Allow UPL to modify the plist here XDocument XDoc; try { XDoc = XDocument.Parse(Text.ToString()); } catch (Exception e) { throw new BuildException("plist is invalid {0}\n{1}", e, Text.ToString()); } XDoc.DocumentType.InternalSubset = ""; UPL.ProcessPluginNode("None", "iosPListUpdates", "", ref XDoc); string result = XDoc.Declaration.ToString() + "\n" + XDoc.ToString().Replace("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"[]>", "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); File.WriteAllText(PListFile, result); } else { File.WriteAllText(PListFile, Text.ToString()); } if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { if (!Directory.Exists(AppDirectory)) { Directory.CreateDirectory(AppDirectory); } File.WriteAllText(AppDirectory + "/Info.plist", Text.ToString()); } return(bSkipDefaultPNGs); }
void CreateWatchOSExtensionProject() { var csproj = inputProject; var suffix = "-watchos-extension"; csproj.SetProjectTypeGuids("{1E2E965C-F6D2-49ED-B86E-418A60C69EEF};" + LanguageGuid); csproj.SetOutputPath("bin\\$(Platform)\\$(Configuration)" + suffix); csproj.SetIntermediateOutputPath("obj\\$(Platform)\\$(Configuration)" + suffix); csproj.RemoveTargetFrameworkIdentifier(); csproj.SetPlatformAssembly("Xamarin.WatchOS"); csproj.SetImport(IsFSharp ? "$(MSBuildExtensionsPath)\\Xamarin\\WatchOS\\Xamarin.WatchOS.AppExtension.FSharp.targets" : "$(MSBuildExtensionsPath)\\Xamarin\\WatchOS\\Xamarin.WatchOS.AppExtension.CSharp.targets"); csproj.FixProjectReferences("-watchos"); csproj.FixArchitectures("i386", "ARMv7k"); csproj.FixInfoPListInclude(suffix); csproj.SetOutputType("Library"); csproj.AddAdditionalDefines("BITCODE", "iPhone", "Release"); csproj.AddAdditionalDefines("XAMCORE_2_0;XAMCORE_3_0;FEATURE_NO_BSD_SOCKETS"); csproj.RemoveReferences("OpenTK-1.0"); var ext = IsFSharp ? "fs" : "cs"; csproj.AddCompileInclude("InterfaceController." + ext, Path.Combine(Harness.WatchOSExtensionTemplate, "InterfaceController." + ext)); csproj.SetExtraLinkerDefs("extra-linker-defs" + Suffix + ".xml"); csproj.SetMtouchUseBitcode(true, "iPhone", "Release"); csproj.SetMtouchUseLlvm(true, "iPhone", "Release"); Harness.Save(csproj, WatchOSExtensionProjectPath); WatchOSExtensionGuid = csproj.GetProjectGuid(); XmlDocument info_plist = new XmlDocument(); var target_info_plist = Path.Combine(TargetDirectory, "Info-watchos-extension.plist"); info_plist.LoadWithoutNetworkAccess(Path.Combine(TargetDirectory, "Info.plist")); BundleIdentifier = info_plist.GetCFBundleIdentifier() + "-watch"; if (BundleIdentifier.Length >= 58) { BundleIdentifier = BundleIdentifier.Substring(0, 57); // If the main app's bundle id is 58 characters (or sometimes more), then the watch extension crashes at launch. radar #29847128. } info_plist.SetCFBundleIdentifier(BundleIdentifier + ".watchkitapp.watchkitextension"); info_plist.SetMinimumOSVersion("2.0"); info_plist.SetUIDeviceFamily(4); info_plist.AddPListStringValue("RemoteInterfacePrincipleClass", "InterfaceController"); info_plist.AddPListKeyValuePair("NSExtension", "dict", string.Format( @" <key>NSExtensionAttributes</key> <dict> <key>WKAppBundleIdentifier</key> <string>{0}.watchkitapp</string> </dict> <key>NSExtensionPointIdentifier</key> <string>com.apple.watchkit</string> ", BundleIdentifier)); if (!info_plist.ContainsKey("NSAppTransportSecurity")) { info_plist.AddPListKeyValuePair("NSAppTransportSecurity", "dict", @" <key>NSAllowsArbitraryLoads</key> <true/> " ); } Harness.Save(info_plist, target_info_plist); }
public static bool GenerateTVOSPList(string ProjectDirectory, bool bIsUE4Game, string GameName, string ProjectName, string InEngineDir, string AppDirectory) { // @todo tvos: THIS! // generate the Info.plist for future use string BuildDirectory = ProjectDirectory + "/Build/TVOS"; bool bSkipDefaultPNGs = false; string IntermediateDirectory = (bIsUE4Game ? InEngineDir : ProjectDirectory) + "/Intermediate/TVOS"; string PListFile = IntermediateDirectory + "/" + GameName + "-Info.plist"; // @todo tvos: This is really nasty - both IOS and TVOS are setting static vars VersionUtilities.BuildDirectory = BuildDirectory; VersionUtilities.GameName = GameName; // read the old file string OldPListData = File.Exists(PListFile) ? File.ReadAllText(PListFile) : ""; // determine if there is a launch.xib string LaunchXib = InEngineDir + "/Build/IOS/Resources/Interface/LaunchScreen.xib"; if (File.Exists(BuildDirectory + "/Resources/Interface/LaunchScreen.xib")) { LaunchXib = BuildDirectory + "/Resources/Interface/LaunchScreen.xib"; } // get the settings from the ini file // plist replacements // @todo tvos: Are we going to make TVOS specific .ini files? ConfigCacheIni Ini = ConfigCacheIni.CreateConfigCacheIni(UnrealTargetPlatform.IOS, "Engine", bIsUE4Game? null : new DirectoryReference(ProjectDirectory)); // bundle display name string BundleDisplayName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleDisplayName", out BundleDisplayName); // bundle identifier string BundleIdentifier; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier", out BundleIdentifier); // bundle name string BundleName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleName", out BundleName); // short version string string BundleShortVersion; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "VersionInfo", out BundleShortVersion); // required capabilities string RequiredCaps = "\t\t<string>arm64</string>\n"; // minimum iOS version string MinVersion; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumTVOSVersion", out MinVersion)) { switch (MinVersion) { case "TVOS_9": MinVersion = "9.0"; break; } } else { MinVersion = "9.0"; } // extra plist data string ExtraData = ""; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalPlistData", out ExtraData); // generate the plist file StringBuilder Text = new StringBuilder(); Text.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); Text.AppendLine("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); Text.AppendLine("<plist version=\"1.0\">"); Text.AppendLine("<dict>"); Text.AppendLine("\t<key>CFBundleDevelopmentRegion</key>"); Text.AppendLine("\t<string>en</string>"); Text.AppendLine("\t<key>CFBundleDisplayName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleDisplayName.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""))); Text.AppendLine("\t<key>CFBundleExecutable</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", bIsUE4Game ? "UE4Game" : GameName.Replace("_", ""))); Text.AppendLine("\t<key>CFBundleIdentifier</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleIdentifier.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""))); Text.AppendLine("\t<key>CFBundleInfoDictionaryVersion</key>"); Text.AppendLine("\t<string>6.0</string>"); Text.AppendLine("\t<key>CFBundleName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleName.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""))); Text.AppendLine("\t<key>CFBundlePackageType</key>"); Text.AppendLine("\t<string>APPL</string>"); Text.AppendLine("\t<key>CFBundleSignature</key>"); Text.AppendLine("\t<string>????</string>"); Text.AppendLine("\t<key>CFBundleVersion</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", VersionUtilities.UpdateBundleVersion(OldPListData))); Text.AppendLine("\t<key>CFBundleShortVersionString</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleShortVersion)); Text.AppendLine("\t<key>LSRequiresIPhoneOS</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIRequiredDeviceCapabilities</key>"); Text.AppendLine("\t<array>"); foreach (string Line in RequiredCaps.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine(Line); } } Text.AppendLine("\t</array>"); /* Text.AppendLine("\t<key>CFBundleIcons</key>"); * Text.AppendLine("\t<dict>"); * Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>CFBundleIconFiles</key>"); * Text.AppendLine("\t\t\t<array>"); * Text.AppendLine("\t\t\t\t<string>Icon29.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon40.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon57.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t</array>"); * Text.AppendLine("\t\t\t<key>UIPrerenderedIcon</key>"); * Text.AppendLine("\t\t\t<true/>"); * Text.AppendLine("\t\t</dict>"); * Text.AppendLine("\t</dict>"); * Text.AppendLine("\t<key>CFBundleIcons~ipad</key>"); * Text.AppendLine("\t<dict>"); * Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>CFBundleIconFiles</key>"); * Text.AppendLine("\t\t\t<array>"); * Text.AppendLine("\t\t\t\t<string>Icon29.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon40.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon50.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon72.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t\t<string>Icon76.png</string>"); * Text.AppendLine("\t\t\t\t<string>[email protected]</string>"); * Text.AppendLine("\t\t\t</array>"); * Text.AppendLine("\t\t\t<key>UIPrerenderedIcon</key>"); * Text.AppendLine("\t\t\t<true/>"); * Text.AppendLine("\t\t</dict>"); * Text.AppendLine("\t</dict>"); * if (File.Exists(LaunchXib)) * { * // TODO: compile the xib via remote tool * Text.AppendLine("\t<key>UILaunchStoryboardName</key>"); * Text.AppendLine("\t<string>LaunchScreen</string>"); * bSkipDefaultPNGs = true; * } * else * { * // this is a temp way to inject the iphone 6 images without needing to upgrade everyone's plist * // eventually we want to generate this based on what the user has set in the project settings * string[] IPhoneConfigs = * { * "Default-IPhone6", "Landscape", "{375, 667}", * "Default-IPhone6", "Portrait", "{375, 667}", * "Default-IPhone6Plus-Landscape", "Landscape", "{414, 736}", * "Default-IPhone6Plus-Portrait", "Portrait", "{414, 736}", * "Default", "Landscape", "{320, 480}", * "Default", "Portrait", "{320, 480}", * "Default-568h", "Landscape", "{320, 568}", * "Default-568h", "Portrait", "{320, 568}", * }; * * Text.AppendLine("\t<key>UILaunchImages~iphone</key>"); * Text.AppendLine("\t<array>"); * for (int ConfigIndex = 0; ConfigIndex < IPhoneConfigs.Length; ConfigIndex += 3) * { * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); * Text.AppendLine("\t\t\t<string>8.0</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); * Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 0])); * Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); * Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 1])); * Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); * Text.AppendLine(string.Format("\t\t\t<string>{0}</string>", IPhoneConfigs[ConfigIndex + 2])); * Text.AppendLine("\t\t</dict>"); * } * * // close it out * Text.AppendLine("\t</array>"); * } * Text.AppendLine("\t<key>UILaunchImages~ipad</key>"); * Text.AppendLine("\t<array>"); * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); * Text.AppendLine("\t\t\t<string>7.0</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); * Text.AppendLine("\t\t\t<string>Default-Landscape</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); * Text.AppendLine("\t\t\t<string>Landscape</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); * Text.AppendLine("\t\t\t<string>{768, 1024}</string>"); * Text.AppendLine("\t\t</dict>"); * Text.AppendLine("\t\t<dict>"); * Text.AppendLine("\t\t\t<key>UILaunchImageMinimumOSVersion</key>"); * Text.AppendLine("\t\t\t<string>7.0</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageName</key>"); * Text.AppendLine("\t\t\t<string>Default-Portrait</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageOrientation</key>"); * Text.AppendLine("\t\t\t<string>Portrait</string>"); * Text.AppendLine("\t\t\t<key>UILaunchImageSize</key>"); * Text.AppendLine("\t\t\t<string>{768, 1024}</string>"); * Text.AppendLine("\t\t</dict>"); * Text.AppendLine("\t</array>”); * Text.AppendLine("\t<key>CFBundleSupportedPlatforms</key>"); * Text.AppendLine("\t<array>"); * Text.AppendLine("\t\t<string>iPhoneOS</string>"); * Text.AppendLine("\t</array>"); * Text.AppendLine("\t<key>MinimumOSVersion</key>"); * Text.AppendLine(string.Format("\t<string>{0}</string>", MinVersion)); * if (!string.IsNullOrEmpty(ExtraData)) * { * ExtraData = ExtraData.Replace("\\n", "\n"); * foreach (string Line in ExtraData.Split("\r\n".ToCharArray())) * { * if (!string.IsNullOrWhiteSpace(Line)) * { * Text.AppendLine("\t" + Line); * } * } * }*/ Text.AppendLine("</dict>"); Text.AppendLine("</plist>"); // write the file out if (!Directory.Exists(IntermediateDirectory)) { Directory.CreateDirectory(IntermediateDirectory); } File.WriteAllText(PListFile, Text.ToString()); if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { if (!Directory.Exists(AppDirectory)) { Directory.CreateDirectory(AppDirectory); } File.WriteAllText(AppDirectory + "/Info.plist", Text.ToString()); } return(bSkipDefaultPNGs); }
public static bool GenerateTVOSPList(string ProjectDirectory, bool bIsUE4Game, string GameName, bool bIsClient, string ProjectName, string InEngineDir, string AppDirectory, UnrealPluginLanguage UPL, string BundleID) { // @todo tvos: THIS! // generate the Info.plist for future use string BuildDirectory = ProjectDirectory + "/Build/TVOS"; bool bSkipDefaultPNGs = false; string IntermediateDirectory = (bIsUE4Game ? InEngineDir : ProjectDirectory) + "/Intermediate/TVOS"; string PListFile = IntermediateDirectory + "/" + GameName + "-Info.plist"; // @todo tvos: This is really nasty - both IOS and TVOS are setting static vars VersionUtilities.BuildDirectory = BuildDirectory; VersionUtilities.GameName = GameName; // read the old file string OldPListData = File.Exists(PListFile) ? File.ReadAllText(PListFile) : ""; // get the settings from the ini file // plist replacements // @todo tvos: Are we going to make TVOS specific .ini files? DirectoryReference DirRef = bIsUE4Game ? (!string.IsNullOrEmpty(UnrealBuildTool.GetRemoteIniPath()) ? new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()) : null) : new DirectoryReference(ProjectDirectory); ConfigHierarchy Ini = ConfigCache.ReadHierarchy(ConfigHierarchyType.Engine, DirRef, UnrealTargetPlatform.IOS); // bundle display name string BundleDisplayName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleDisplayName", out BundleDisplayName); // bundle identifier string BundleIdentifier; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleIdentifier", out BundleIdentifier); if (!string.IsNullOrEmpty(BundleID)) { BundleIdentifier = BundleID; } // bundle name string BundleName; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "BundleName", out BundleName); // short version string string BundleShortVersion; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "VersionInfo", out BundleShortVersion); // required capabilities string RequiredCaps = "\t\t<string>arm64</string>\n"; // minimum iOS version string MinVersion; if (Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "MinimumTVOSVersion", out MinVersion)) { switch (MinVersion) { case "TVOS_9": MinVersion = "9.0"; break; } } else { MinVersion = "9.0"; } // extra plist data string ExtraData = ""; Ini.GetString("/Script/IOSRuntimeSettings.IOSRuntimeSettings", "AdditionalPlistData", out ExtraData); // create the final display name, including converting all entities for XML use string FinalDisplayName = BundleDisplayName.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""); FinalDisplayName = FinalDisplayName.Replace("&", "&"); FinalDisplayName = FinalDisplayName.Replace("\"", """); FinalDisplayName = FinalDisplayName.Replace("\'", "'"); FinalDisplayName = FinalDisplayName.Replace("<", "<"); FinalDisplayName = FinalDisplayName.Replace(">", ">"); // generate the plist file StringBuilder Text = new StringBuilder(); Text.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); Text.AppendLine("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); Text.AppendLine("<plist version=\"1.0\">"); Text.AppendLine("<dict>"); Text.AppendLine("\t<key>CFBundleDevelopmentRegion</key>"); Text.AppendLine("\t<string>en</string>"); Text.AppendLine("\t<key>CFBundleDisplayName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", EncodeBundleName(BundleDisplayName, ProjectName))); Text.AppendLine("\t<key>CFBundleExecutable</key>"); string BundleExecutable = bIsUE4Game ? (bIsClient ? "UE4Client" : "UE4Game") : (bIsClient ? GameName + "Client" : GameName); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleExecutable)); Text.AppendLine("\t<key>CFBundleIdentifier</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleIdentifier.Replace("[PROJECT_NAME]", ProjectName).Replace("_", ""))); Text.AppendLine("\t<key>CFBundleInfoDictionaryVersion</key>"); Text.AppendLine("\t<string>6.0</string>"); Text.AppendLine("\t<key>CFBundleName</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", EncodeBundleName(BundleName, ProjectName))); Text.AppendLine("\t<key>CFBundlePackageType</key>"); Text.AppendLine("\t<string>APPL</string>"); Text.AppendLine("\t<key>CFBundleSignature</key>"); Text.AppendLine("\t<string>????</string>"); Text.AppendLine("\t<key>CFBundleVersion</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", VersionUtilities.UpdateBundleVersion(OldPListData, InEngineDir))); Text.AppendLine("\t<key>CFBundleShortVersionString</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", BundleShortVersion)); Text.AppendLine("\t<key>LSRequiresIPhoneOS</key>"); Text.AppendLine("\t<true/>"); Text.AppendLine("\t<key>UIRequiredDeviceCapabilities</key>"); Text.AppendLine("\t<array>"); foreach (string Line in RequiredCaps.Split("\r\n".ToCharArray())) { if (!string.IsNullOrWhiteSpace(Line)) { Text.AppendLine(Line); } } Text.AppendLine("\t</array>"); Text.AppendLine("\t<key>TVTopShelfImage</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>TVTopShelfPrimaryImage</key>"); Text.AppendLine("\t\t<string>Top Shelf Image</string>"); Text.AppendLine("\t\t<key>TVTopShelfPrimaryImageWide</key>"); Text.AppendLine("\t\t<string>Top Shelf Image Wide</string>"); Text.AppendLine("\t</dict>"); Text.AppendLine("\t<key>CFBundleIcons</key>"); Text.AppendLine("\t<dict>"); Text.AppendLine("\t\t<key>CFBundlePrimaryIcon</key>"); Text.AppendLine("\t\t<string>App Icon</string>"); Text.AppendLine("\t</dict>"); Text.AppendLine("\t<key>UILaunchStoryboardName</key>"); Text.AppendLine("\t<string>LaunchScreen</string>"); // write the iCloud container identifier, if present in the old file if (!string.IsNullOrEmpty(OldPListData)) { int index = OldPListData.IndexOf("ICloudContainerIdentifier"); if (index > 0) { index = OldPListData.IndexOf("<string>", index) + 8; int length = OldPListData.IndexOf("</string>", index) - index; string ICloudContainerIdentifier = OldPListData.Substring(index, length); Text.AppendLine("\t<key>ICloudContainerIdentifier</key>"); Text.AppendLine(string.Format("\t<string>{0}</string>", ICloudContainerIdentifier)); } } Text.AppendLine("</dict>"); Text.AppendLine("</plist>"); // Create the intermediate directory if needed if (!Directory.Exists(IntermediateDirectory)) { Directory.CreateDirectory(IntermediateDirectory); } if (UPL != null) { // Allow UPL to modify the plist here XDocument XDoc; try { XDoc = XDocument.Parse(Text.ToString()); } catch (Exception e) { throw new BuildException("plist is invalid {0}\n{1}", e, Text.ToString()); } XDoc.DocumentType.InternalSubset = ""; UPL.ProcessPluginNode("None", "iosPListUpdates", "", ref XDoc); string result = XDoc.Declaration.ToString() + "\n" + XDoc.ToString().Replace("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"[]>", "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"); File.WriteAllText(PListFile, result); } else { File.WriteAllText(PListFile, Text.ToString()); } if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac) { if (!Directory.Exists(AppDirectory)) { Directory.CreateDirectory(AppDirectory); } File.WriteAllText(AppDirectory + "/Info.plist", Text.ToString()); } return(bSkipDefaultPNGs); }