用捷径实现更方便的字体管理
一直以来,iOS 因缺少原生的字体管理功能而饱受诟病,虽然苹果在 WWDC 2019 对 iOS 和 iPadOS 增加了字体管理功能,但到目前的 Beta 2 版本中仍无法直接安装下载的字体,长期使用的如 Anyfont 的字体管理类 App 对大体积中文字体支持不佳、优化欠缺,使我诞生了自己做一个字体管理应用的念头,可自己当时又没有 Mac。山穷水尽,柳暗花明,偶然瞥见了捷径,想到用捷径实现字体管理,故有此文。
思路
在 iOS 13 Beta 2 中,通过自带的文件应用虽可以识别字体文件,但仍无法直接安装,和以往一样,需要把字体文件嵌入描述文件即 XML 格式的
*.mobileconfig
,另考虑到 iOS 缺少良好的中文字体下载 App,添加一个良好的中文字体下载的平台是必要的。![](https://bbs.5g110.cn/wp-content/uploads/2019/10/1570263501-1259e09a57a6574.png)
在这里选用 Google Fonts 和汉仪字库为主要的字体获取途径,同时支持安装下载好的字体文件。整体流程并不复杂,但要获得好的体验,细节处理十分重要,希望你能读到最后。
Google Fonts
Google Fonts 有可寻的 API,因此只需先访问 Google Fonts 官网,选择需要的字体再通过调用 API 就可以完成下载。
![](https://bbs.5g110.cn/wp-content/uploads/2019/10/1570263925-30ea0435296a589.png)
我们可以通过此示例来从
fonts.google.com
下载字体。首先选择需要的字体后,通过 Safari 的共享菜单运行该捷径从而获取到 URL,观察 URL 结构,使用正则表达式 (?<=selection\.family=).*$
匹配 family=
后面的选中的字体名称,将字体名称添加到 https://fonts.google.com/download?family=
尾部得到下载链接。支持选中多个字体同时下载。需要注意的是,下载得到的字体可能为 *.zip
的压缩文件,所以需要在 Repeat
步骤中嵌套一个条件判断,如果该下载的文件后缀中含有 .zip
,则需要对其进行解压才能得到字体文件,具体请参见示例。汉仪字库
由于没有找到汉仪字库供个人使用的 API,我们需要通过一些特殊方法来获取字体。笔者首先想到的是通过网页源代码提取网页渲染时加载项中的字体链接。
![](https://bbs.5g110.cn/wp-content/uploads/2019/10/1570263956-86da2a3bde0a493.png)
经过实践后,问题接踵而至,一方面是捷径内部需要重新加载一遍网页并转换为
*.md
费时费力,另一方面是难以用简单的方式在大量字符中提取到需要的字体链接。三思后我选择使用 MitM 来获取 API,再通过 API 完成字体下载。![](https://bbs.5g110.cn/wp-content/uploads/2019/10/1570263990-caaf4441e581a20.png)
以“汉仪字酷堂邓氏小楷W”为例,开启支持 MitM 和 HTTP Capture 的 App 如 Surge、Quantumult X 等,通过 PC 视图下的 Safari 在汉仪字库官网选择并下载需要的字体。观察 URL 尾部的数字为
6411
,以 Surge 为例在 REQUEST BODY 中可以找到 fontdetail=get&fontId=6411
的请求,反推找到 REQUEST URL 为 http://www.hanyi.studio/hanyiwebsite/fontmanagement/fontmanagerhandler.ashx
和 REQUEST METHOD 为 POST
。同理用正则表达式 (?<=productdetail.php\?id=).*$
获取 Safari 共享菜单共享的 URL 尾部数字。最后用捷径的 Get contents of URL
向 REQUEST URL 模拟 POST 请求得到上图左侧 JSON 格式的 RESPOND BODY,直接用捷径的 Get Value for
步骤就可以获得字体名称 ProductName
和字体下载链接 ProductFileUrl
。![](https://bbs.5g110.cn/wp-content/uploads/2019/10/1570264054-791b1df3d28adfd.png)
在模拟 POST 请求时需要注意 Headers 尽量和抓取的 Headers 一致,避免请求失败,具体请参考此示例捷径。
处理字体
获取字体后,需要对字体进行处理并嵌入到描述文件中才可以使用。对于描述文件,其结构以下图左侧为例。
![](https://bbs.5g110.cn/wp-content/uploads/2019/10/1570264053-44f437ced647ec3.png)
左侧用灰色标出的段落是我们要进行修改的地方。
UUID
生成流程如上图右侧,可通过 List->Random Item->Replace
实现,不使用在线的 UUID 生成器 API,提高了捷径可用度。Hash
则通过计算字体文件的 SHA1 得到。Name
为之前获取的字体名称。最后将字体文件 base64 encode 后替换 Base64 Encode
。此外优化不可忽视,之所以保存到「文件」而不是在捷径跳转到 Safari 直接安装,是因为跳转时要把文件用 URL Encode 转化为字符链接,耗费性能,对于体积较大的中文字体,会造成设备卡死;另外进行 base64 处理时不分段,加快速度;描述文件去格式化压缩为一行,削减体积。在这里同样提供一个示例捷径供参考。安装字体
在「文件」中选择生成好的字体描述文件就可以将字体直接安装到设置中,通过 iCloud 云盘或 Airdrop 可直接同步到其它设备,在各种第三方 App 中使用十分方便,当然也存在一些兼容问题,部分 App 无法使用,需要 Apple 和开发者们一起努力解决。
细节处理
一个工具仅仅能实现它的功能是远远不够的,还需要便捷高效的使用体验,而这些都离不开细节上的处理优化。对于一个捷径而言,其本身可以直接运行或通过共享菜单运行。在这里我的思考是,直接运行时没有指令输入,因此引导用户到字体下载网站或跳转到「文件」选择字体文件更佳;而共享菜单运行是有指令输入的,故适合作为主要的执行流程。对于直接运行和共享菜单运行的判断可以用
Count Items
步骤实现。对于共享菜单,输入的内容可以是一条链接、多条链接、一个字体文件、多个字体文件等,因此需要对输入内容用 Repeat
步骤拆分,再逐个进行类型判断和过滤,巧用 Add to Variable
和 Set Variable
步骤实现批量操作。写在最后
最后附上 Anyfonts 捷径,其实去年就写完了的,投稿 Shortcuts Gallery 结果石沉大海;另这依旧是第一版,也许还有许多地方可以完善,欢迎大家反馈建议。名字是奔着律师函去的,因为实在想不到什么好的名字。一直想做一个字体管理软件的,奈何复读了一年,荒废了时间。匆匆成文,如有错误,还请斧正。欢迎关注。