Starting from iOS 13, CTFontManager has the following function:
@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)?)
However, Asset Catalog does not have any way to add "Font Assets".
What I've tried:
- took font
KanitRegular.ttf(PostScript name isKanit-Regular) here. - created Data Asset named
Kanit-Regularin the asset catalog. - Renamed font file to
Kanit-Regular.ttfand put it into the data asset.
Data Asset's Contents.json now looks like this:
{
"data" : [
{
"filename" : "Kanit-Regular.ttf",
"idiom": "universal",
"universal-type-identifier" : "public.truetype-ttf-font"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
- Tried to load this font via
CTFontManager
like this:
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
}
}
After this, getting errors printed:
▿ 1 element
- 0 : Error Domain=NSPOSIXErrorDomain Code=22 "Invalid argument" UserInfo={CTFontManagerErrorFontAssetNameKey=(
"Kanit-Regular"
)}
Is there any way to make it work?
Got it working by making the following:
Kanit-Regulardata asset withfontsOn-Demand Resource Tag (tag name can be the name of your preference,fontsis just the example).fontstag intoInitial Install TagsPrefetched Resource Tags sectionFontsCapability inSigning & Capabilitiesand tick all boxes in itlike this:
Outcome
When scope is passed as
.persistentor.user, on initial call ofCTFontManagerRegisterFontsWithAssetNamesfunction the user will be asked to install fonts into the system, which is not what I really need. In case the scope is.processor.none, the sameerrorsoutput is returned as provided at the end of the question.Although this function does not fit my needs, I at least validated that it is working. Maybe someone finds it useful.