Example #1
0
        internal static string?ResolveXCFramework(PDictionary plist, string platformName, string?variant, string architectures)
        {
            // plist structure https://github.com/spouliot/xcframework#infoplist
            var bundle_package_type = (PString)plist ["CFBundlePackageType"];

            if (bundle_package_type?.Value != "XFWK")
            {
                return(null);
            }
            var available_libraries = plist.GetArray("AvailableLibraries");

            if ((available_libraries == null) || (available_libraries.Count == 0))
            {
                return(null);
            }

            var platform = platformName.ToLowerInvariant();
            var archs    = architectures.Split(new char [] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (PDictionary item in available_libraries)
            {
                var supported_platform = (PString)item ["SupportedPlatform"];
                if (supported_platform.Value != platform)
                {
                    continue;
                }
                // optional key
                var supported_platform_variant = (PString)item ["SupportedPlatformVariant"];
                if (supported_platform_variant?.Value != variant)
                {
                    continue;
                }
                var supported_architectures = (PArray)item ["SupportedArchitectures"];
                // each architecture we request must be present in the xcframework
                // but extra architectures in the xcframework are perfectly fine
                foreach (var arch in archs)
                {
                    bool found = false;
                    foreach (PString xarch in supported_architectures)
                    {
                        found = String.Equals(arch, xarch.Value, StringComparison.OrdinalIgnoreCase);
                        if (found)
                        {
                            break;
                        }
                    }
                    if (!found)
                    {
                        return(String.Empty);
                    }
                }
                var library_path       = (PString)item ["LibraryPath"];
                var library_identifier = (PString)item ["LibraryIdentifier"];
                return(GetActualLibrary(Path.Combine(library_identifier, library_path)));
            }
            return(String.Empty);
        }
        void RegisterFonts(PDictionary plist)
        {
            if (FontFilesToRegister == null || FontFilesToRegister.Length == 0)
            {
                return;
            }

            // https://developer.apple.com/documentation/swiftui/applying-custom-fonts-to-text

            // Compute the relative location in the app bundle for each font file
            var          prefixes       = BundleResource.SplitResourcePrefixes(ResourcePrefix);
            const string logicalNameKey = "_ComputedLogicalName_";

            foreach (var item in FontFilesToRegister)
            {
                var logicalName = BundleResource.GetLogicalName(ProjectDir, prefixes, item, !string.IsNullOrEmpty(SessionId));
                item.SetMetadata(logicalNameKey, logicalName);
            }

            switch (Platform)
            {
            case ApplePlatform.iOS:
            case ApplePlatform.TVOS:
            case ApplePlatform.WatchOS:
            case ApplePlatform.MacCatalyst:
                // Fonts are listed in the Info.plist in a UIAppFonts entry for iOS, tvOS, watchOS and Mac Catalyst.
                var uiAppFonts = plist.GetArray("UIAppFonts");
                if (uiAppFonts == null)
                {
                    uiAppFonts           = new PArray();
                    plist ["UIAppFonts"] = uiAppFonts;
                }
                foreach (var item in FontFilesToRegister)
                {
                    uiAppFonts.Add(new PString(item.GetMetadata(logicalNameKey)));
                }
                break;

            case ApplePlatform.MacOSX:
                // The directory where the fonts are located is in the Info.plist in the ATSApplicationFontsPath entry for macOS.
                // It's relative to the Resources directory.
                // Make sure that all the fonts are in the same directory in the app bundle
                var allSubdirectories      = FontFilesToRegister.Select(v => Path.GetDirectoryName(v.GetMetadata(logicalNameKey)));
                var distinctSubdirectories = allSubdirectories.Distinct().ToArray();
                if (distinctSubdirectories.Length > 1)
                {
                    Log.LogError(MSBStrings.E7083 /* "All font files must be located in the same directory in the app bundle. The following font files have different target directories in the app bundle:" */, CompiledAppManifest.ItemSpec);
                    foreach (var fonts in FontFilesToRegister)
                    {
                        Log.LogError(null, null, null, fonts.ItemSpec, 0, 0, 0, 0, MSBStrings.E7084 /* "The target directory is {0}" */, fonts.GetMetadata(logicalNameKey));
                    }
                }
                else
                {
                    plist.SetIfNotPresent("ATSApplicationFontsPath", string.IsNullOrEmpty(distinctSubdirectories [0]) ? "." : distinctSubdirectories [0]);
                }
                break;

            default:
                throw new InvalidOperationException(string.Format(MSBStrings.InvalidPlatform, Platform));
            }
        }