Keel — Enterprise / Private Distribution

公开分发(GitHub Release + CocoaPods Trunk)见 architecture.md § 分发渠道(iOS)roadmap.md。本文档只覆盖非公开场景:客户不希望自己使用 Keel 这件事在 public registry 上被检索到,或 Appunvs 内部需要私有发版通道。

适用场景

  • 企业客户:合同里要求 SDK 不出现在 public registry / package index
  • 付费 license 闭源版本:和 Apache 2.0 公版功能不同的 enterprise build
  • 预发 / RC 通道:未对外公开的内部测试版本

公版与私有版的 Keel.xcframework 二进制可以完全相同;区别只在分发渠道


三种私有渠道

1. 私有 GitHub repo(推荐,覆盖 90% 场景)

最简单:fork keel/ 到私有 GitHub repo(例如 github.com/appunvs/keel-enterprise),公开版的 Package.swift + Keel.podspec 改成指向私有 release 的 URL

// keel-enterprise/Package.swift
.binaryTarget(
  name: "Keel",
  url: "https://github.com/appunvs/keel-enterprise/releases/download/v0.1.0/Keel.xcframework.zip",
  checksum: "..."
),

客户用法:

// Their Package.swift — needs git+SSH or PAT for private repo
.package(url: "https://github.com/appunvs/keel-enterprise.git", from: "0.1.0")

或 SSH:

.package(url: "git@github.com:appunvs/keel-enterprise.git", from: "0.1.0")

客户需要的访问凭据:

  • SSH:在 GitHub 添加 deploy key 或 SSH key
  • HTTPS:在 Git credential 或 keychain 配 personal access token

GitHub Release 的 zip 本身也是私有访问:未授权用户的 SPM 下载会拿到 401。

优点

  • 复用 GitHub Release 流程,跟公版 release 一模一样
  • 不需要单独 CDN / 对象存储
  • 标准 SPM 工具链,零额外配置

缺点

  • 客户需要 GitHub 账号 + repo 访问权限
  • 不适合不想用 GitHub 的客户

2. 自托管 CDN + Package Registry

对 GitHub access 有顾虑或合规要求外部托管的客户:

  • Keel.xcframework.zip 放自托管 CDN(阿里云 OSS / 腾讯云 COS / 自建 S3)
  • 私有 Package.swift repo 单独放(可以是私有 GitLab / Gitee / 内部 git server)
// Private keel manifest repo's Package.swift
.binaryTarget(
  name: "Keel",
  url: "https://sdk-cdn.appunvs.com/keel/0.1.0/Keel.xcframework.zip",
  checksum: "..."
),

CDN URL 可以加签名(presigned URL),但 SPM 不支持 dynamic auth header,所以要么:

  • URL 长期有效(依赖 IP allowlist 或不可枚举的路径名)
  • 签名 URL 嵌入 manifest(每次轮换需重发 Package.swift commit)

优点

  • 完全不依赖 GitHub
  • 可控的访问审计

缺点

  • 多一层基础设施(CDN)需要运维
  • SPM auth 模型受限

3. 私有 Swift Package Registry(SPM 5.7+ 官方支持)

SE-0339(SPM 5.7+)支持自托管的 Swift Package Registry,对接企业内部包管理(类似 npm Verdaccio / Artifactory)。

# 客户机器一次性配置
swift package-registry login https://registry.appunvs.com --token <PAT>
// 客户的 Package.swift
.package(id: "appunvs.keel", from: "0.1.0")

支持的私有 registry 实现(2026):

  • GitHub Packages(GitHub Enterprise plans)
  • JFrog Artifactory(commercial)
  • Sonatype Nexus(self-hosted, 社区版免费)
  • 自实现 registry server(SE-0339 协议 + REST API)

优点

  • 最”正规”的私有分发方式,对齐 Apple 长期方向
  • 客户体验最贴近公版(from: 版本声明)

缺点

  • 适配成本最高(要么买 Artifactory 之类,要么自建 registry)
  • 客户端 SPM 配置略复杂(要预先 swift package-registry login
  • 适合规模化企业市场,不适合早期单租户场景

CocoaPods 兼容渠道(私有 spec repo)

如果客户走 CocoaPods 而非 SPM(罕见,但 pod-only 模块依赖客户可能选这条路):

# 一次性:客户机器添加私有 spec repo
pod repo add appunvs-private git@github.com:appunvs/private-specs.git
# 客户的 Podfile 顶部
source 'git@github.com:appunvs/private-specs.git'
source 'https://cdn.cocoapods.org/'   # 官方 fallback

target 'MyApp' do
  pod 'Keel', '~> 0.1'
end

Appunvs 侧维护一个私有 git repo appunvs/private-specs 镜像 CocoaPods 的标准目录结构:

Specs/
  K/
    e/
      e/
        Keel/
          0.1.0/
            Keel.podspec
          0.1.1/
            Keel.podspec
          ...

发版命令:

pod repo push appunvs-private keel/Keel.podspec

pod trunk push 几乎一样的工作流,只是 push 到自己的 git 而不是 CocoaPods 中央。


选哪个?

客户画像推荐渠道
单个 / 少量企业客户私有 GitHub repo(方案 1)—— 启动成本最低
不能用 GitHub 但用 SPM自托管 CDN(方案 2)
大规模 enterprise,已有 Artifactory私有 Swift Package Registry(方案 3)
客户 pod-only私有 CocoaPods spec repo(兼容方案)

短期 dogfooding / 内部使用:直接走方案 1,开销最小。


二进制保密的额外考量

私有分发只能防止 registry / source 维度的曝光,不能防:

  • 逆向:xcframework 是 ARM64 Mach-O,反汇编门槛低
  • 二次分发:拿到 xcframework 的人物理上可以再分发

如果有真实的反逆向需求,需要在 Keel.xcframework 本身做 obfuscation / 字符串加密 / runtime check 等,独立于本文档讨论的分发层。