CompileAppManifest CreateTask(string?tmpdir = null, ApplePlatform platform = ApplePlatform.iOS)
        {
            if (string.IsNullOrEmpty(tmpdir))
            {
                tmpdir = Cache.CreateTemporaryDirectory();
            }

            var task = CreateTask <CompileAppManifest> ();

            task.AssemblyName           = "AssemblyName";
            task.AppBundleName          = "AppBundleName";
            task.CompiledAppManifest    = new TaskItem(Path.Combine(tmpdir, "TemporaryAppManifest.plist"));
            task.DefaultSdkVersion      = Sdks.GetAppleSdk(platform).GetInstalledSdkVersions(false).First().ToString();
            task.SdkPlatform            = PlatformFrameworkHelper.GetSdkPlatform(platform, false);
            task.SdkVersion             = task.DefaultSdkVersion;
            task.TargetFrameworkMoniker = TargetFramework.GetTargetFramework(platform, true).ToString();

            return(task);
        }
Example #2
0
        public override bool Execute()
        {
            var mainInfoPath = PlatformFrameworkHelper.GetAppManifestPath(Platform, AppBundlePath);

            if (!File.Exists(mainInfoPath))
            {
                Log.LogError(7040, AppBundlePath, MSBStrings.E7040, AppBundlePath);
                return(false);
            }

            var plist = PDictionary.FromFile(mainInfoPath);

            var bundleIdentifier = plist.GetCFBundleIdentifier();

            if (string.IsNullOrEmpty(bundleIdentifier))
            {
                Log.LogError(7041, mainInfoPath, MSBStrings.E7041, mainInfoPath);
                return(false);
            }

            var executable = plist.GetCFBundleExecutable();

            if (string.IsNullOrEmpty(executable))
            {
                Log.LogError(7042, mainInfoPath, MSBStrings.E7042, mainInfoPath);
            }

            var supportedPlatforms = plist.GetArray(ManifestKeys.CFBundleSupportedPlatforms);
            var platform           = string.Empty;

            if (supportedPlatforms == null || supportedPlatforms.Count == 0)
            {
                Log.LogError(7043, mainInfoPath, MSBStrings.E7043, mainInfoPath);
            }
            else
            {
                platform = (PString)supportedPlatforms[0];
            }

            // Validate UIDeviceFamily
            var deviceTypes    = plist.GetUIDeviceFamily();
            var deviceFamilies = deviceTypes.ToDeviceFamily();

            AppleDeviceFamily[]  validFamilies    = null;
            AppleDeviceFamily [] requiredFamilies = null;

            switch (Platform)
            {
            case ApplePlatform.MacCatalyst:
                requiredFamilies = new AppleDeviceFamily [] {
                    AppleDeviceFamily.IPad,
                };
                goto case ApplePlatform.iOS;

            case ApplePlatform.iOS:
                validFamilies = new AppleDeviceFamily[] {
                    AppleDeviceFamily.IPhone,
                    AppleDeviceFamily.IPad,
                };
                break;

            case ApplePlatform.WatchOS:
                validFamilies = new AppleDeviceFamily[] { AppleDeviceFamily.Watch };
                break;

            case ApplePlatform.TVOS:
                validFamilies = new AppleDeviceFamily[] { AppleDeviceFamily.TV };
                break;

            default:
                Log.LogError("Invalid platform: {0}", Platform);
                break;
            }

            if (validFamilies != null)
            {
                if (validFamilies.Length == 0)
                {
                    Log.LogError(7044, mainInfoPath, MSBStrings.E7044, mainInfoPath);
                }
                else
                {
                    foreach (var family in deviceFamilies)
                    {
                        if (Array.IndexOf(validFamilies, family) == -1)
                        {
                            Log.LogError(7044, mainInfoPath, MSBStrings.E7044_A, mainInfoPath, family);
                        }
                    }
                }
            }

            if (requiredFamilies != null)
            {
                foreach (var family in requiredFamilies)
                {
                    if (!deviceFamilies.Contains(family))
                    {
                        Log.LogError(7044, mainInfoPath, MSBStrings.E7044_A, mainInfoPath, family);
                    }
                }
            }

            var mainShortVersionString = plist.GetCFBundleShortVersionString();
            var mainVersion            = plist.GetCFBundleVersion();

            if (Directory.Exists(Path.Combine(AppBundlePath, "PlugIns")))
            {
                foreach (var plugin in Directory.GetDirectories(Path.Combine(AppBundlePath, "PlugIns"), "*.appex"))
                {
                    ValidateAppExtension(plugin, bundleIdentifier, mainShortVersionString, mainVersion);
                }
            }

            if (Directory.Exists(Path.Combine(AppBundlePath, "Watch")))
            {
                foreach (var watchApp in Directory.GetDirectories(Path.Combine(AppBundlePath, "Watch"), "*.app"))
                {
                    ValidateWatchApp(watchApp, bundleIdentifier, mainShortVersionString, mainVersion);
                }
            }

            return(!Log.HasLoggedErrors);
        }
Example #3
0
        public override bool Execute()
        {
            TargetArchitecture architectures, deviceArchitectures, target = TargetArchitecture.Default;
            string             targetOperatingSystem;
            PDictionary        plist, device;
            PString            value, os;

            switch (PlatformFrameworkHelper.GetFramework(TargetFrameworkIdentifier))
            {
            case ApplePlatform.WatchOS:
                targetOperatingSystem = "watchOS";
                break;

            case ApplePlatform.TVOS:
                targetOperatingSystem = "tvOS";
                break;

            default:
                targetOperatingSystem = "iOS";
                break;
            }

            if (!Enum.TryParse(Architectures, out architectures))
            {
                Log.LogError("Invalid architectures: '{0}'.", Architectures);
                return(false);
            }

            if ((plist = PObject.FromString(TargetiOSDevice) as PDictionary) == null)
            {
                Log.LogError("Failed to parse the target device information.");
                return(false);
            }

            if (!plist.TryGetValue("device", out device))
            {
                Log.LogError("No target device found.");
                return(false);
            }

            if (!device.TryGetValue("architecture", out value))
            {
                Log.LogError("No device architecture information found.");
                return(false);
            }

            if (!Enum.TryParse(value.Value, out deviceArchitectures) || deviceArchitectures == TargetArchitecture.Default)
            {
                Log.LogError("Invalid target architecture: '{0}'", value.Value);
                return(false);
            }

            if (!device.TryGetValue("os", out os))
            {
                Log.LogError("No device operating system information found.");
                return(false);
            }

            if (os.Value != targetOperatingSystem || (architectures & deviceArchitectures) == 0)
            {
                // the TargetiOSDevice property conflicts with the build configuration (*.user file?), do not build this project for a specific device
                DeviceSpecificIntermediateOutputPath = IntermediateOutputPath;
                DeviceSpecificOutputPath             = OutputPath;
                TargetArchitectures   = Architectures;
                TargetDeviceOSVersion = string.Empty;
                TargetDeviceModel     = string.Empty;

                return(!Log.HasLoggedErrors);
            }

            for (int bit = 0; bit < 32; bit++)
            {
                var architecture = (TargetArchitecture)(1 << bit);

                if ((architectures & architecture) == 0)
                {
                    continue;
                }

                if ((deviceArchitectures & architecture) != 0)
                {
                    target = architecture;
                }
            }

            TargetArchitectures = target.ToString();

            if (!device.TryGetValue("model", out value))
            {
                Log.LogError("No device model information found.");
                return(false);
            }

            TargetDeviceModel = value.Value;

            if (!device.TryGetValue("os-version", out value))
            {
                Log.LogError("No iOS version information found.");
                return(false);
            }

            TargetDeviceOSVersion = value.Value;

            // Note: we replace ',' with '.' because the ',' breaks the Mono AOT compiler which tries to treat arguments with ','s in them as options.
            var dirName = TargetDeviceModel.ToLowerInvariant().Replace(",", ".") + "-" + TargetDeviceOSVersion;

            DeviceSpecificIntermediateOutputPath = Path.Combine(IntermediateOutputPath, "device-builds", dirName) + "/";
            DeviceSpecificOutputPath             = Path.Combine(OutputPath, "device-builds", dirName) + "/";

            return(!Log.HasLoggedErrors);
        }
 public static AppleSdk GetSdk(string targetFrameworkIdentifier)
 {
     return(GetSdk(PlatformFrameworkHelper.GetFramework(targetFrameworkIdentifier)));
 }