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 扩展,可按以下顺序处理:
- 从两个扩展 target 的配置来源中移除新增的
NSExtensionPrincipalClass,并检查是否存在NSExtensionMainStoryboard。 - 检查 Debug、Release 以及 Archive 使用的配置,确认没有通过 Build Settings、
.xcconfig或脚本再次写入这些键。 - 清理构建后重新生成 archive,检查新产物中的两个 Info.plist。
- 分别重新测试设备安装和 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 同样安装失败。最终需要同一套配置生成的产物通过两个阶段的检查。
备注:内容仅供参考。
