🌚

Kam's Online Notebook


输出 Framework 的一些琐事

最近接手了一个针对未成年防沉迷认证的半成品 SDK,魔改了一番(API 调整、项目组织结构、输出多个业务版本、打包),简单记录一下。

琐事

Framework

Framework 在 Apple 定义上看就是组织资源的一种动态库。如果你把 mach-o 设置 static library,通常没啥问题,但是如果 framework 包含 bundle 资源,那么代码中通过 -bundleForClass: 是找不到对应的,static library 的 code 已经被 link 到 main execute,那么你只能获得 main bunlde,当然也是有 workaround:就是去资源目录里面去查找;或者要求接入方把这个 bundle 放到 main bundle(尽管是脚本做这个事情)。都不太优雅,所以通常有资源的 SDK 弄成的动态库,会比较舒服。

然后对外头文件还是得用 umbrella header,这样就能用上 module feature。

Inteface

隐藏一些没必要暴露的 API,就用 extension 建立 PublicClass+Private.h 文件,仅供内部访问,保持对外输出到 API 是干净、无冗余的。另外有一些入参对象,如有必要尽量,让它遵循 NSCopying 协议、或者说,使用它的 immutable 副本。设想,caller 传入了一个 context 字典,SDK 内部读取上面的值 context[account] 处理业务,而 caller 在外面不小心改了这个字典内容,就会产生一些异常。

Packing

项目内的打包还是有点问题:

  1. 打包脚本使用 xcodebuild build 而不是 archive;

  2. lipo 合并 ARM 和 Intel 两个 archs 的 framework 的时候,把 Intel framework 当作 destination 了。什么意思呢?即拷贝了 Intel simulator framework 作为最终产物,然后用 lipo 把 ARM 的二进制合并到 simulator framework 了,那么里面的 Info.plist 就充满了 simulator 的字眼(DTSDKName、DTPlatformName、CFBundleSupportedPlatforms);

  3. 2021 年还在使用 Xcode 13 输出 2 slice framework 然后让接入方在打包的时候用脚本 remove Intel slice 实在有点体验不佳。

第一个不好说算不算问题,但是因为 build 没有产生 dsym 文件,那么给到接入方就会很不舒服,改为 archive 就舒服了;另外说起 archive 要提一下 -arhivePath 是相对 pwd 的路径,怪不得改脚本的时候一指定一个绝对路径,每次 archive 完总是找不到 build artifacts;😅

第二个可能是通病,同一个互联网同一个 lipo script?这样会导致 App 审核被拒,这锅背不起,幸好隔壁部门有类似经历,咱们提前规避;

第三个就是改下 lipo 为 -create-xcframework 了,不过 xcframework 的组织方式还是有点冗余,显然多个 framework 里的很多资源其实是相同(谁会在意 developer 的 disk storage),但是好处就在于接入方不用纠结怎么移除 Intel arch 的 slice。

Others

  1. 消灭所有警告 ⚠️
  2. 对项目进行静态分析并解决所有 issues 🔨
  3. 具备级别分类的日志工具,方便双方排查问题 📝

EOF

— Aug 16, 2021