简体   繁体   中英

What's the definition of Font Asset in the Asset Catalog?

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 is Kanit-Regular ) here .
  • created Data Asset named Kanit-Regular in the asset catalog.
  • Renamed font file to Kanit-Regular.ttf and 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:

  • Tag the Kanit-Regular data asset with fonts On-Demand Resource Tag (tag name can be the name of your preference, fonts is just the example).
  • Put fonts tag into Initial Install Tags Prefetched Resource Tags section

初始安装标签资源标签部分

  • Add Fonts Capability in Signing & Capabilities and tick all boxes in it

在此处输入图像描述

  • Implement bundle resource access request before registering fonts

like this:

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
            }
        }
    }
}

Outcome

When scope is passed as .persistent or .user , on initial call of CTFontManagerRegisterFontsWithAssetNames function the user will be asked to install fonts into the system, which is not what I really need. In case the scope is .process or .none , the same errors output 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 will find it useful.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM