You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apple WWDC2019字体注册示例代码遇报错,咨询其开发价值

关于WWDC 2019字体注册示例代码的疑问与解答

问题背景

我在学习Apple WWDC 2019的字体相关视频时,看到一段用于向系统注册字体的示例代码:

static func registerFamilies(_ names: [FontFamily], _ registrationHandler: 
    (([Error], Bool) -> Bool)?) {
    let fontURLs = names.flatMap({ $0.urls })
    CTFontManagerRegisterFontURLs(fontURLs as CFArray, .persistent, true) {
        (errors: CFArray, done: Bool) -> Bool in
        return processHandler(errors: errors, done: done, registrationHandler) 
    }
}

运行这段代码时出现了三个错误:

  • Cannot find type "FontFamily" in scope;
  • Static methods must only be declared on a type
  • Cannot find processHandler in scope.

我推测未定义的FontFamily类型导致了其中两个错误,但不清楚该类型的具体定义;同时我需要自行实现processHandler函数。我已导入CoreText和Foundation框架,想知道自己遗漏了什么?

另外我找到了更简洁的实现版本:

let fontUrl = Bundle.main.url(forResource: fileName, withExtension: "ttf")

CTFontManagerRegisterFontURLs([fontUrl] as CFArray, .persistent, true) { (errors, done) -> Bool in
        if(done) {
            print("Done")
        }
        print(errors as Array)
        return true
    }

我的核心疑问是:Apple提供的这种复杂且不完整的示例对开发者有什么益处?

问题解答

1. 代码错误的原因与修复

  • 找不到FontFamily类型:FontFamily是示例里自定义的结构体,不是系统自带API,你得自己定义它,比如用来封装同一个字体家族下的所有字体文件URL:
struct FontFamily {
    let urls: [URL]
    // 还可按需添加字体家族名称等属性,方便管理
}
  • 静态方法必须归属某个类型:静态方法不能独立存在于全局作用域,得把registerFamilies方法放到类、结构体或枚举内部,比如封装成一个工具类:
class FontRegistrationHelper {
    static func registerFamilies(_ names: [FontFamily], _ registrationHandler: (([Error], Bool) -> Bool)?) {
        let fontURLs = names.flatMap({ $0.urls })
        CTFontManagerRegisterFontURLs(fontURLs as CFArray, .persistent, true) {
            (errors: CFArray, done: Bool) -> Bool in
            return processHandler(errors: errors, done: done, registrationHandler) 
        }
    }
}
  • 找不到processHandler:这是示例预留的自定义处理函数,需要你自行实现,作用是将CoreText返回的CFArray类型错误转换为Swift可处理的Error数组,再回调传入的处理闭包:
private static func processHandler(errors: CFArray, done: Bool, _ registrationHandler: (([Error], Bool) -> Bool)?) -> Bool {
    let swiftErrors = errors as? [Error] ?? []
    return registrationHandler?(swiftErrors, done) ?? true
}

2. Apple复杂示例的意义

Apple的示例代码并非为了直接复制粘贴运行,而是展示工程化的最佳实践,具体益处包括:

  • 批量场景的结构化管理:示例针对的是批量注册多个字体家族的场景,比如一个字体包含常规、粗体、斜体等多个文件,用FontFamily可以将同一家族的字体文件统一管理,比零散处理单个URL更清晰。
  • 错误处理的扩展性:通过registrationHandler和processHandler的设计,允许开发者自定义错误处理逻辑——无论是记录日志、向用户提示,还是执行重试操作,都能灵活实现,而非像简洁示例那样仅做简单打印。
  • 代码复用性:封装成静态方法后,项目中任何需要注册字体的地方都能直接调用,避免重复编写相同逻辑。
  • 完整展示API能力:CTFontManagerRegisterFontURLs本身支持批量注册、持久化注册等特性,简洁示例只用到了基础功能,而WWDC示例则引导开发者理解API的设计意图,充分利用其全部能力。

简洁示例适合快速实现单个字体的注册需求,但如果是大型项目,需要管理多套字体、自定义错误处理逻辑,WWDC的示例就是更具参考价值的工程化方案,能帮你写出更健壮、易维护的代码。

内容的提问来源于stack exchange,提问作者benwiggy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 18:44:52