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
相关产品推荐
相关产品推荐

