PAYATHON 2026

iOS 扩展的 NSExtensionPrincipalClass 提交校验与安装冲突如何解决?

数据小陈

结论

安装日志显示,当前设备不允许 com.apple.appintents-extension 包含 NSExtensionPrincipalClass 或 NSExtensionMainStoryboard。应先从这两个 App Intents 扩展中移除新增的 NSExtensionPrincipalClass,并确认没有配置 NSExtensionMainStoryboard。

添加 $(PRODUCT_MODULE_NAME).ShortcutsAppIntentsExtension 虽然通过了提交校验,却会导致设备拒绝安装,不能作为有效修复。现有材料无法确定提交端为何要求这些键,也无法确认某个 Xcode 版本能否解决这一冲突。

两个错误分别说明什么

提交校验提示缺少 NSExtensionMainStoryboard 或 NSExtensionPrincipalClass;设备安装日志则显示,当前 extension point 禁止声明这两个键。两条错误发生在不同阶段,不能只依据其中一条修改配置。

安装日志中的相关信息是:

Domain: MIInstallerErrorDomain
Code: 152
LegacyErrorString = AppexBundleContainsClassOrStoryboard;

日志还给出了具体限制:

which is not allowed for the extension point com.apple.appintents-extension

这说明当前安装失败发生在扩展配置校验阶段。现有错误没有指向 Swift 类名解析失败,也没有日志依据表明调整类名或改用 storyboard 能解决问题。

先检查实际归档中的 Info.plist

应核对构建产物中的配置。最终归档中的配置可能受到 Build Settings、不同构建配置或构建脚本的影响,不能只看项目中的源 Info.plist。

先找到 archive 中的所有扩展:

archive="/path/to/YourApp.xcarchive"
find "$archive/Products" -type d -name '*.appex' -print

将路径替换成实际 archive 路径。随后检查错误中提到的两个扩展:

archive="/path/to/YourApp.xcarchive"

for plist in \
  "$archive/Products/Applications/iOS App.app/PlugIns/iOS App Intents.appex/Info.plist" \
  "$archive/Products/Applications/iOS App.app/Watch/watchOS App.app/PlugIns/watchOS App Intents.appex/Info.plist"
do
  printf '\n%s\n' "$plist"
  /usr/libexec/PlistBuddy -c 'Print :NSExtension' "$plist"
done

应用和扩展名称来自问题中的路径,实际执行时需与归档内容一致。这些命令只用于读取配置,不能代替安装和提交验证。

重点核对三个值:

  • NSExtensionPointIdentifier 是否为预期的 com.apple.appintents-extension。
  • NSExtensionPrincipalClass 是否仍然存在。
  • NSExtensionMainStoryboard 是否仍然存在。

对于日志所指的 App Intents 扩展,应保留正确的 extension point,并移除两个被安装器禁止的键。相关配置片段例如:

<key>NSExtension</key>
<dict>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.appintents-extension</string>
</dict>

这只是相关片段,不是完整的 Info.plist。不要因此删除扩展的其他必要配置,也不要把其他类型扩展的配置一并改成这个值。

从配置来源修复,再重新构建

如果确认这两个 target 都是预期的 App Intents 扩展,可按以下顺序处理:

  1. 从两个扩展 target 的配置来源中移除新增的 NSExtensionPrincipalClass,并检查是否存在 NSExtensionMainStoryboard。
  2. 检查 Debug、Release 以及 Archive 使用的配置,确认没有通过 Build Settings、.xcconfig 或脚本再次写入这些键。
  3. 清理构建后重新生成 archive,检查新产物中的两个 Info.plist。
  4. 分别重新测试设备安装和 archive 校验,记录各自的完整结果。

修改项目配置来源后,应重新构建。直接修改已签名的 .app 或 .appex 中的 Info.plist 会影响签名,也无法保证下一次构建保留修改。

删除后仍然无法提交怎么办

如果新 archive 中两个扩展的 extension point 都正确,且没有这两个键,但提交校验仍要求添加它们,冲突就还没有解决。此时可以核对扩展 target 是否沿用了其他扩展类型的配置,并使用所选 Xcode 的对应模板建立最小工程进行对照。

若最小工程也能复现相同冲突,可以向 Apple 提交反馈,附上两个阶段的错误、归档中的 NSExtension 字典、Xcode 和 SDK 版本,以及设备系统版本。

问题给出的环境是 Xcode 26.3、iphoneos26.2 SDK 和 iOS 26.4。仅凭这些版本号,不能认定 SDK 与设备系统版本不同就是原因,也不能断言升级或降级必然有效。若尝试另一套工具链,应重新构建,并同时验证安装和提交两个环节。

不要只在 Release 中添加 NSExtensionPrincipalClass 来绕过问题:原始日志已说明 Release 同样安装失败。最终需要同一套配置生成的产物通过两个阶段的检查。

备注:内容仅供参考。