跳至正文
兼容性与性能 发布机构:西安守界御盾信息安全技术有限公司 274 views

Kotlin Multiplatform App 加固怎么验收:共享模块、XCFramework 与双端发布指南

从阅读进入评估 如果你正在评估 App 加固方案,可以先看官网能力边界,再提交一个真实包做 PoC。
查看御盾官网

答案:Kotlin Multiplatform(KMP)项目接入 App 加固时,应把共享模块、Android Release 产物和 iOS Native/XCFramework 产物作为三类对象分别验收。Android 正常不代表 iOS 已通过,iOS Archive 能导出也不代表共享逻辑、Native 依赖、签名和关键业务路径均无问题;只有在固定 Kotlin、Compose、AGP、Gradle、Xcode、架构、最终签名包与业务路径后,才能给出某个候选版本的双端兼容结论。

KMP 允许团队在 Android、iOS 等平台之间按需共享业务逻辑,也可以结合 Compose Multiplatform 共享 UI。Kotlin 官方将 KMP 核心技术以及 Android、iOS 支持列为稳定,Compose Multiplatform 的 Android、iOS 与桌面支持也处于稳定状态;但“技术稳定”不等于任何插件、构建变体、Native 依赖、系统版本或加固策略天然兼容。App 加固的工作,是把最终发布对象和真实业务路径纳入可复核范围,而不是把共享代码视为一个抽象概念。

本文面向 KMP/Compose Multiplatform 项目的研发负责人、Android 与 iOS 工程师、移动安全、测试和发布团队。文中依据 Kotlin、JetBrains 与 Android 官方公开资料给出验收框架;不包含客户包、私钥、构建路径、真实日志或规避系统与安全检查的做法,也不代表御盾已完成任一特定 KMP 项目的实测。

摘要

KMP 的共享逻辑会分别进入 Android 与 iOS 的交付链。本文把双端兼容性拆成候选对象、构建版本、共享模块、平台产物、关键路径、最终签名和回滚七个检查面;它用于定义项目验收方法,不将框架稳定性或单端现象写成未经执行的产品兼容承诺。

读者对象

本文适合计划在 Android 与 iOS 共用业务逻辑的 KMP 团队,也适合负责 Compose Multiplatform、Kotlin/Native、XCFramework、CocoaPods、Swift Package、R8、AAB 或移动发布门禁的工程人员。对采购和安全负责人而言,它可用来判断加固服务是否区分共享模块与最终发布包,而不是只展示一张“支持跨平台”的功能表。

核心结论

  • KMP 的共享模块需要两端分别进入最终产物:Android 是应用 Release/AAB 交付,iOS 是 Kotlin/Native 与宿主 Archive/IPA 交付。
  • KMP 稳定、Compose Multiplatform 平台支持稳定,不等于当前项目的所有构建版本、插件、系统、架构和保护策略组合已通过。
  • Android 侧应重点核对变体、R8、Consumer Rules、AAB、ABI 与 Native 依赖;iOS 侧应重点核对 target、XCFramework slice、嵌入、Archive 与最终签名。
  • 双端 PoC 应把通过、失败和未覆盖项写入同一份交付记录,且不要求项目提供生产私钥。

验收目标与非目标

本文的目标是让项目以同一版本的真实 Release 对象建立双端兼容性基线,并将问题收敛到 Android 构建、iOS 集成、共享逻辑、平台依赖或保护策略的责任边界。

目标 验收对象 可以形成的结论 非目标
固定候选身份 Android Release、iOS Archive/IPA 当前比较对象可追溯 不公开客户包和签名材料
检查共享逻辑 commonMain 与实际业务路径 指定路径是否完成执行 不推断全部功能均正常
检查 Android 交付 variant、R8、AAB、ABI、SO 当前 Android 候选的发布边界 不用 Debug 代替 Release
检查 iOS 交付 target、Framework、Archive、IPA 当前 iOS 候选的发布边界 不用模拟器代替真机渠道
支持回滚 已知稳定候选与触发条件 故障后存在恢复路径 不承诺平台审核结果

KMP 项目为什么不能按“一份代码、一次验收”处理

KMP 的核心价值是可选择地共享代码,而不是把所有平台都压缩成同一种交付物。一个典型移动项目会包含 commonMain 中的共享领域逻辑、网络或状态管理,也会包含 androidMainiosMain 中的平台实现。Android 侧共享代码通常与应用模块一起进入 JVM/DEX 交付;iOS 侧则通过 Kotlin/Native 编译进入 Native 目标,并可能以 Framework、XCFramework、CocoaPods 或 Swift Package 的方式接入宿主工程。

这带来至少四条与加固验收直接相关的事实:

  • 同一共享模块在 Android 与 iOS 的编译器、二进制格式、符号与链接方式不同,不能用一端包体状态替代另一端。
  • Android 的应用变体、AAB split、R8/Consumer Rules、JNI/SO 与渠道签名会改变最终发布对象;iOS 则要处理 iosArm64、iosSimulatorArm64、Framework slice、Archive、Entitlements 与 IPA 签名。
  • expect/actual、平台 SDK、网络、存储、推送、支付或安全组件会在各端落地为不同实现。共享逻辑的结果相同,不代表初始化、授权或错误恢复流程相同。
  • KMP、Compose、Gradle、AGP 和 Xcode 都存在版本兼容关系。升级其中任一层后,旧的验收结论不能自动沿用。

因此,一份合格的项目报告应写清“哪个候选包、哪个框架和工具版本、哪个平台、哪条路径已经执行”,而不是写“支持 KMP”这样的无限外推结论。

事实依据与脱敏证据

# 公开事实 在 KMP 加固验收中的用途 不能得出的结论
1 Kotlin 官方将 Android 与 iOS 列为 KMP 核心稳定平台 双端项目可以采用共享逻辑与平台实现并存的验收模型 不是任何项目自动兼容证明
2 Kotlin 官方说明 KMP 可只共享部分模块 需要明确本项目共享的是网络、领域逻辑、UI 还是其他模块 不能假定所有代码都在 commonMain
3 Kotlin/Native 为 iOS 等平台编译 Native 二进制 iOS 需按 Native 产物、target 与宿主集成单独核对 不能用 Android DEX 结果代替 iOS 结论
4 Android KMP Library plugin 是单变体模型 Release/flavor 设计要在正确的 Android 模块和最终应用上复核 不代表项目不能拥有正式发布变体
5 Kotlin 官方要求关注 Kotlin、Gradle、AGP 与 Xcode 兼容关系 升级任一构建工具应重新核对候选对象 不能把旧报告直接沿用到新版本
6 Compose Multiplatform 官方版本表列出平台、最低系统和 64 位范围 报告需写清实际 Compose 版本、iOS 目标与架构 不可把某一版本规则套用到全部版本
7 Android 官方说明 build type 和 flavor 会组合为最终 variant Android 端必须验证目标 Release/渠道产物 编译通过不等于用户安装对象通过

来源报告事实映射

以下内容将今天的跨平台主题与公开资料对应,用于说明为什么 KMP 是独立搜索与验收问题,而不是把已发布的 Flutter、React Native、Unity 或 XCFramework 页面换一个标题重复发布。

本次公开事实 页面中的工程用途 公开边界
既有框架页分别覆盖 Flutter、Hermes、Unity IL2CPP 与 XCFramework 新页仅补齐 KMP shared module 与双端 Native 产物 不将旧页结论复制为 KMP 结论
KMP Android/iOS 核心支持处于稳定状态 将 KMP 纳入跨平台兼容性中心导航 不声称已完成客户项目实测
Android KMP library plugin 缺少传统多变体能力 提醒项目在最终应用 Release/渠道对象复核 不断言任何构建方式必然失败
Compose 版本存在明确 iOS 最低版本和架构范围 将版本、目标和架构列为验收字段 不把单一版本范围泛化到其他版本
Flutter/RN/Unity/KMP 的业务载体不同 用不同专项页承接不同框架故障意图 不创建同义的跨端页面竞争关键词
线上兼容性页面已有 PoC 与性能中心 将新页链接至固定承接页完成转化路径 不虚构搜索排名、流量或转化数据
公开验收记录:
  框架: Kotlin Multiplatform
  结论类型: 方法与范围说明
  必填对象:
    - Android Release 候选
    - iOS Archive 或最终 IPA 候选
    - Kotlin、Gradle、AGP、Xcode 版本
    - 已执行关键路径
  状态枚举: [已执行, 通过, 失败, 未覆盖]
  对外边界: 未执行的版本、插件、系统和业务路径不作通过声明

先固定六组候选对象

下面的分组不是要求项目把生产签名材料交给加固服务,而是为了让每个差异都有可定位的对象。最终签名可以由项目方在受控环境完成。

组别 对象 用途 不能替代什么
1 未加固 Android Release APK/AAB 建立 Android 业务与性能基线 不能替代最终渠道安装包
2 Android 基础保护候选 判断最低保护范围下的集成状态 不能替代目标保护策略
3 Android 目标保护与最终签名包 检查 AAB、split、渠道、升级与业务路径 不能替代 iOS 验收
4 未加固 iOS Archive 建立 iOS 宿主、Framework 与业务基线 不能替代导出 IPA 或目标分发渠道
5 iOS 保护候选 检查 Native 产物、嵌入对象和策略范围 不能替代最终签名与安装验证
6 iOS 最终签名 IPA 检查安装、升级、关键路径和回滚 不能外推未覆盖的设备或系统

每一组至少关联业务提交、Kotlin 版本、Compose Multiplatform 版本(如使用)、Gradle、AGP、Xcode、依赖锁、目标系统、ABI/架构、构建配置、加固策略版本与渠道。这里的“关联”可以是项目内部台账或脱敏报告字段,不需要公开真实包名、完整证书指纹或供应商私有信息。

Android:关注 KMP 模块如何进入最终 Release

Android 侧首先要分清项目使用的是普通 Android 应用/库配置,还是新的 Kotlin Multiplatform Android Library plugin。Android 官方说明,该 KMP library plugin 是单变体设计,不支持传统 Android Library 中的 build type 与 product flavor;如果项目仍需要多变体或依赖 BuildConfigexternalNativeBuild 等能力,应让这些职责处于适合的 Android 模块中,并在最终应用变体上验证。

这并不意味着单变体一定会导致加固问题,而是提醒团队不能沿用“每个 Library 都有 Debug/Release 和渠道 flavor”的假设。发布前至少检查以下内容:

检查面 KMP 项目需要确认的事实 加固验收中的判断
共享代码 commonMain 依赖、序列化、反射与平台 actual 实现 共享模块是否随最终 Release 进入正确产物
构建变体 app 的 Release/flavor 与 KMP Library 的单变体边界 不把开发变体结果外推到正式渠道
R8 与规则 反射、序列化、JNI 回调、SDK Consumer Rules 原始 Release 与候选包分别复核关键入口
Native 依赖 SO、ABI、加载阶段、CInterop 或平台 SDK 不把 KMP 共享模块误认为没有 Native 风险
AAB 交付 split、动态特性、最终签名和商店产物 以用户实际安装对象而非本地单 APK 结论为准

若 Android 端异常,推荐的归因顺序是:先验证未加固 Release 是否可复现;随后比较基础保护候选和目标策略候选;再核对变体、R8、依赖、ABI、SO 及首次调用路径。不要因为共享模块存在就直接把所有异常归给 Kotlin,也不要先关闭全部保护来换取一次启动成功。

技术拆解:共享模块、平台模块与二进制边界

commonMain 适合承载业务规则、数据模型、网络抽象、同步逻辑或状态管理,但它依然会通过 Android 与 iOS 各自的编译链进入不同产物。androidMain 可能接入 Android SDK、JNI、文件系统、推送或 Play 服务;iosMain 可能接入 Swift/Objective-C、Keychain、系统权限、CocoaPods 或 Swift Package。加固验收不应把这三层合并成“一个 KMP 模块”,而应确认每层是否在最终发布对象中保留预期边界。

如项目使用序列化、依赖注入、反射或代码生成,Android Release 需要重点查看 R8、保留规则和 Consumer Rules;iOS 则需要关注 Kotlin/Native 导出、Framework 接口、链接与资源。若共享层调用平台 actual 实现,问题也可能只在平台组件首次执行时出现。因此,测试用例应覆盖实际调用 shared code 的功能,而不仅仅是加载包含 shared code 的首页。

字段动态时间线

阶段 Android 侧记录 iOS 侧记录 处理原则
构建输入 Kotlin、Gradle、AGP、variant、依赖锁 Kotlin、Xcode、target、依赖接入方式 固定版本,不混入临时修改
原始 Release APK/AAB、ABI、关键路径基线 Archive、Framework/slice、关键路径基线 先确认未加固对象表现
保护候选 策略、R8、SO/资源差异 策略、嵌入对象、Archive 差异 一次仅改变一个变量
最终签名 渠道、split、覆盖升级 IPA、Entitlements、目标分发 以实际交付对象复核
异常处置 最小复现、版本回退、回归 最小复现、版本回退、回归 将未覆盖项保留在报告中

iOS:关注 Kotlin/Native、XCFramework 与宿主 Archive 的边界

iOS 侧的共享代码并不以 Android DEX 形式存在。Kotlin/Native 可将 Kotlin 编译为 iOS 所需的 Native 二进制,实际项目可能通过 XCFramework、CocoaPods、Swift Package 或手工嵌入方式接入 Swift/SwiftUI 宿主。每一种接入方式都有自己的 target、slice、资源、签名和 Archive 行为。

验收时应至少记录:

  • 当前 iOS target,例如 iosArm64 与 iosSimulatorArm64;模拟器验证不能替代真机发布产物。
  • Framework 是静态还是动态,是否包含资源 Bundle、Kotlin/Native 依赖或 Objective-C/Swift 导出接口。
  • Xcode 与 Kotlin Multiplatform 兼容版本;Kotlin 官方建议配置项目时核对 Kotlin、Gradle、AGP 与 Xcode 的相互兼容性。
  • 宿主是否采用 CocoaPods、Swift Package、直接 Embed 或其他集成方式;同一 XCFramework 的嵌入与签名责任不能混写。
  • Archive 与最终 IPA 中的 Framework、Extension、PrivacyInfo.xcprivacy、Entitlements、Profile 与发布签名状态。

Compose Multiplatform 也应写明版本和平台范围。以官方兼容性资料为例,Compose Multiplatform 1.11.1 将 iOS 最低版本列为 iOS 14,并只支持 64 位平台。项目若使用其他版本,应以其对应的官方兼容表为准;不能把某个版本的最低系统、架构或 Web 状态套用到所有 KMP 项目。

对于 iOS 侧异常,先比较未加固 Archive 与保护候选,再检查 Framework slice、嵌入方式、导出接口、资源和宿主签名;最后在最终 IPA 的目标渠道完成安装、启动、共享功能调用、前后台、升级与回滚验证。更多 iOS 二进制 SDK 的输入与发布身份检查,可参考 iOS XCFramework 接入 App 加固怎么验收

关键业务路径不要只选首页

KMP 项目的问题可能在共享模块第一次处理网络响应、数据库迁移、序列化、加密、文件、推送回调或平台桥接时才出现。首页或登录页能显示,只能说明最短启动链已走通。建议由业务方从下表选择至少一条真正使用共享逻辑的路径,并为 Android、iOS 各自记录结果。

业务类别 推荐路径 为什么需要双端单独记录
账号与会话 登录、刷新令牌、退出再登录 网络、存储与平台安全组件实现可能不同
数据同步 首次拉取、离线缓存、冲突恢复 序列化、数据库和文件系统边界不同
支付或权益 下单、支付回调、权益刷新 平台 SDK、深链、签名和渠道规则不同
内容与媒体 下载、解压、播放或模型加载 资源、Native 库和内存边界不同
消息与推送 注册、前台接收、点击回跳 Android/iOS 生命周期和权限模型不同
高风险操作 修改安全设置、绑定账户或关键提交 应结合服务端验证与可解释失败路径

记录结果时,使用“已执行、通过、失败、未覆盖”四种状态即可;不应把一次人工观察写成全机型、全版本或所有插件的兼容承诺。

工程落地:把双端矩阵接入发布门禁

团队可以在每次准备发布时维护一张最小双端矩阵。Android 行记录 targetSdk、ABI、Release/flavor、AAB 或 APK、Native 依赖与最终签名;iOS 行记录最低系统、target、Framework/XCFramework、依赖接入方式、Archive、IPA 与分发方式。两端共用的列包括业务提交、KMP/Compose 版本、关键路径、保护范围、状态、异常归因、回滚对象和复核日期。

对高频发版项目,矩阵可以被 CI/CD 读取并和构建编号关联,但“自动化存在”不等于实际功能已验证。对于支付、登录、数据同步、加密、推送、媒体或 AI 模型等高风险路径,建议保留项目方可复核的执行结果,并在未执行时明确标记。这样既能减少版本变化造成的盲区,也能在发生回归时快速确定应回退的是框架、依赖、构建配置还是保护策略。

攻防视角

KMP 能减少双端业务规则的不一致,但共享逻辑也可能让高价值校验、请求构造或资源访问模式在两个平台上呈现相似入口。防守目标不是把客户端宣称为绝对可信,而是提高关键逻辑和完整性入口被随意修改的成本,并让服务端继续根据账号、会话和业务动作作最终判断。Android 与 iOS 侧的二进制、运行时和签名边界不同,所以防护验证也要分别落地。

如果团队因一次兼容故障直接取消全部完整性或运行时保护,可能把短期问题变成长期发布风险。更合理的做法是保留基线候选,缩小故障变量,针对真实问题实施最小修正并再次验证关键路径。任何异常处理都应保留可回滚选择,而不是依赖不可复现的人工打包。

风险边界

本文不提供 KMP、Kotlin/Native、Android 或 iOS 的绕过、注入、重签、密钥提取或攻击复现内容;不公开客户输入,也不对第三方 SDK 安全性作判断。御盾的作用是帮助项目保护并验证约定范围内的应用交付对象,不能替代框架供应方修复缺陷、替代 Apple/Google 审核,或在没有真实候选包和关键路径结果时承诺全面兼容。

从故障现象回到责任边界

现象 先检查什么 常见错误判断 下一步
Android 正常,iOS 首次调用异常 XCFramework、Native target、导出接口、Archive 认为 shared code 一定有逻辑 bug 与未加固 Archive 比较并缩小 iOS 集成变量
iOS 正常,Android Release 失败 R8、变体、Consumer Rules、ABI 与 AAB 只检查 Debug APK 固定 Release/flavor 和最终用户安装对象
双端仅升级后异常 Kotlin/Compose/AGP/Gradle/Xcode 兼容关系 把版本升级和保护策略混为一次变更 逐步回退并一次只变更一层
仅渠道或覆盖升级失败 最终签名、版本码、split、旧数据与回滚包 用新装成功代替升级通过 在同一渠道复核覆盖安装和恢复
仅功能页失败 该功能的共享逻辑、平台 SDK、Native 依赖 首页正常就是全面通过 对功能路径建立最小复现与回归项

御盾可以帮助项目把候选对象、保护范围、产物差异、关键路径和回滚条件纳入同一份验收记录;但第三方 SDK 的产品缺陷、平台审核决定、未提供的环境和未执行的路径,都不能被宣传为已解决。高价值业务仍应由服务端结合账号、会话和业务规则做最终裁决,客户端不应成为唯一可信边界。

常见误区

KMP 已稳定,就不用做双端 PoC

稳定说明核心技术遵循相应的兼容承诺,不等于项目中的全部 SDK、插件、系统版本、Native 库、签名方式和保护策略组合都已被验证。双端 PoC 的目标正是确认当前项目选择的组合。

iOS 模拟器通过即可代表 IPA 通过

模拟器与真机 target、架构和签名环境不同。真正发布的判断对象是目标分发方式下的 Archive 与最终 IPA。

Android 构建成功即可说明 KMP Library 变体正确

新的 KMP Android Library plugin 采用单变体模型,构建成功并不会自动证明应用 Release/flavor、依赖匹配、R8 和最终 AAB 的行为正确。

为了解决兼容问题可以让供应方持有生产私钥

不需要。项目方可控制最终签名;验收应围绕候选包身份、构建条件、保护策略、关键路径和发布对象建立可追溯关系。

FAQ

KMP 项目能像普通 Android App 一样加固吗?

Android 交付部分仍需要按 Android Release、R8、ABI、SO、AAB 和最终签名包验收;但不能忽略同一共享模块在 iOS Native/XCFramework 中的另一条发布路径。KMP 项目应做双端分开记录、统一管理的 PoC。

Compose Multiplatform 是否需要额外写一套验收?

若项目共享 UI,应在共享逻辑验收之外增加页面导航、状态恢复、平台组件嵌入、系统版本和架构范围。具体最低版本与支持状态以正在使用的 Compose 版本官方兼容表为准。

KMP 使用 CocoaPods 或 Swift Package 时,检查重点不同吗?

共同重点是最终 Archive 中的真实依赖、Framework/slice、资源与签名;不同点在于依赖解析、嵌入方式和版本锁定。报告应写明接入方式,而不是只写“iOS 已集成”。

可以先只验证一个平台吗?

可以,但报告必须明确另一个平台未覆盖。先完成一端的候选对象和关键路径基线,再扩展到另一端,通常比将两个平台的异常混在一起排查更有效。

相关页面与下一步

若你正在处理 KMP 共享模块、iOS XCFramework 或 Android Release 在加固后出现的差异,可提交目标平台、当前框架版本、Release 候选对象和一条关键业务路径,先确定双端兼容性验证范围,再进入正式发布安排。

公开依据

相关阅读