Swift Markdown Kit · DOCS

授权

授权

授权做什么,不做什么

不控制功能。有没有授权,每一项能力的渲染结果完全一致。没有授权的构建只是 在渲染内容的角落带一个 Unlicensed · macdeer.com 小角标,并在控制台打印一行 说明原因。整个约束机制就这些。

这是刻意设计的。你可以先接进来、渲染真实内容、做性能分析、跑通 CI,再决定付款; 而万一线上某次授权解析失败,你的 App 也照常工作。

授权范围

授权是一个签名文件,用 Ed25519 在设备上校验,不会向任何服务器发请求。

范围覆盖
Apple Team ID该团队签名的所有 App。
Bundle identifier仅列出的那些 App。

一份授权可以同时带两者,此时两者都必须匹配。多数客户想要的是 Team ID 范围: 一个文件覆盖你发布的所有 App,新增 target 也不需要重新签发。

购买得到的是 Team ID 授权,在账户中心绑定一次即可。绑定是永久的 —— 签名文件 无法回收 —— 所以确认前请核对 Team ID。需要 bundle 范围的授权可以联系我们签发。

试用与生产

类型有效条件
试用当前日期早于授权的 validUntil —— 自签发起 30 天。
生产SDK 构建的发布日期不晚于授权的 updatesUntil

生产授权这条规则是关键,值得说准确:生产授权从不按日期过期,也从不读取设备 时钟。它约束的是你可以运行哪些 SDK 构建,比较的是构建自身的发布时间戳与 你的更新窗口。

由此带来的结果正是你想要的:

  • 已经上架的 App 永远继续工作。窗口结束不会反过来把它们停掉。
  • 用户设备时间不准也没有影响,因为根本不读时钟。
  • 续期买的是升级的权利,不是继续运行的权利。

续期就是拿到一份 updatesUntil 更晚的新授权文件。替换掉旧的即可,其他什么都 不用改。

关于模拟器

模拟器既没有描述文件,也没有带 team 前缀的钥匙串,因此读不到 Apple Team ID。 所以 Team ID 范围的授权在模拟器上会显示角标 —— 这是预期行为,控制台会明确 说明,真机、TestFlight 和 App Store 构建都不受影响。

如果你希望模拟器上也没有角标,可以向我们索取一份 bundle 范围的授权,与团队授权 并存。

除此之外,各处的校验完全一致。没有 Debug 豁免,没有模拟器豁免,不存在任何 表现不同的环境 —— 这也正是为什么开发时看到的效果,就是上线后的效果。

排查角标

一行输出能回答几乎所有问题:

print(MarkdownRenderKit.licenseDiagnostics())

它会说明:哪个密钥验签通过、由哪个签发环境签发、Team ID 从哪里读到(或为什么 读不到)、授权覆盖了哪些 bundle identifier 与当前运行的是哪个,以及 SDK 的发布 时间与你的 updatesUntil 的对比。

想在代码里判断 —— 比如写一条 debug 断言:

let status = renderer.licenseStatus
if !status.isLicensed {
    print("unlicensed:", status.diagnostic?.code ?? "unknown")
}

diagnosticnil 时,且仅当此时,表示授权已生效。全部错误码见 API 参考

最常见的两种原因

licenseTeamIdentifierUnavailable —— 你在模拟器上用了 Team ID 范围的授权。 属于预期,见上一节。

licenseUnknownSigningKey —— 授权由本构建不信任的密钥签发。实际情况通常是: 测试环境签发的试用授权配了生产 SDK 构建,或者反过来。联系我们按正确环境重签 即可。

获取授权

试用授权免费,索取即发。购买后获得针对你 Team ID 的生产授权,以及 12 个月的 更新服务。