À partir d'iOS 13, CTFontManager a la fonction suivante:

@discussion Font assets are extracted from the asset catalog and registered. This call must be made after the completion handler of either NSBundleResourceRequest beginAccessingResourcesWithCompletionHandler: or conditionallyBeginAccessingResourcesWithCompletionHandler: is called successfully.
Name the assets using Postscript names for individual faces, or family names for variable/collection fonts. The same names can be used to unregister the fonts with CTFontManagerUnregisterFontDescriptors. In iOS, fonts registered with the persistent scope are not automatically available to other processes. Other process may call CTFontManagerRequestFonts to get access to these fonts.

@param      fontAssetNames
            Array of font name assets in asset catalog.

...

CTFontManagerRegisterFontsWithAssetNames(_ fontAssetNames: CFArray, _ bundle: CFBundle?, _ scope: CTFontManagerScope, _ enabled: Bool, _ registrationHandler: ((CFArray, Bool) -> Bool)?)

Cependant, le catalogue d'actifs ne dispose d'aucun moyen d'ajouter des «actifs de police».

Ce que j'ai essayé:

  • a pris la police KanitRegular.ttf (le nom PostScript est Kanit-Regular) ici.
  • a créé l'élément de données nommé Kanit-Regular dans le catalogue d'actifs.
  • Fichier de police renommé Kanit-Regular.ttf et placez-le dans l'élément de données.

L'élément de données Contents.json ressemble maintenant à ceci:

{
   "data" : [
    {
      "filename" : "Kanit-Regular.ttf",
      "idiom": "universal",
      "universal-type-identifier" : "public.truetype-ttf-font"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}
  • J'ai essayé de charger cette police via CTFontManager

Comme ça:

func registerFont() {
    var cfBundle: CFBundle?
    if let bundle = Bundle(for: type(of: self)) {
        cfBundle = CFBundleCreate(kCFAllocatorDefault, bundle.bundleURL as CFURL)
    }
    CTFontManagerRegisterFontsWithAssetNames(["Kanit-Regular"] as CFArray, cfBundle, .persistent, true) { (errors, done) -> Bool in
        print(errors)
        return done
    }
}

Après cela, impression de errors:

▿ 1 element
  - 0 : Error Domain=NSPOSIXErrorDomain Code=22 "Invalid argument" UserInfo={CTFontManagerErrorFontAssetNameKey=(
    "Kanit-Regular"
)}

Existe-t-il un moyen de le faire fonctionner?

1
Eugene Dudnyk 12 mars 2021 à 17:06

1 réponse

Meilleure réponse

Je l'ai fait fonctionner en faisant ce qui suit:

  • Balisez l'élément de données Kanit-Regular avec le tag de ressource à la demande fonts (le nom du tag peut être le nom de votre préférence, fonts n'est qu'un exemple)
  • Insérez la balise fonts dans la section Initial Install Tags balises de ressources pré-extraites

Initial Install Tags Resource Tags section

  • Ajoutez la fonctionnalité Fonts dans Signing & Capabilities et cochez toutes les cases.

enter image description here

  • Mettre en œuvre la demande d'accès aux ressources de l'ensemble avant d'enregistrer les polices

Comme ça:

func registerFont() {
    var cfBundle: CFBundle?
    var resourceRequest: NSBundleResourceRequest?
    if let bundle = Bundle(for: type(of: self)) {
        resourceRequest = NSBundleResourceRequest(tags: Set(arrayLiteral: "fonts"), bundle: bundle)
        cfBundle = CFBundleCreate(kCFAllocatorDefault, bundle.bundleURL as CFURL)
    }
    resourceRequest?.beginAccessingResources() { error in
        if let error = error {
            print(error)
        } else {
            CTFontManagerRegisterFontsWithAssetNames(["Kanit-Regular"] as CFArray, cfBundle, .persistent, true) { (errors, done) -> Bool in
                print(errors)
                return done
            }
        }
    }
}

Résultat

Lorsque la portée est passée en tant que .persistent ou .user, lors de l'appel initial de la fonction CTFontManagerRegisterFontsWithAssetNames, l'utilisateur sera invité à installer des polices dans le système, ce qui n'est pas ce dont j'ai vraiment besoin. Dans le cas où la portée est .process ou .none, la même sortie errors est renvoyée comme fournie à la fin de la question.

Bien que cette fonction ne corresponde pas à mes besoins, j'ai au moins validé qu'elle fonctionne. Peut-être que quelqu'un le trouvera utile.

0
Eugene Dudnyk 12 mars 2021 à 19:59