Swift-React Native项目调用CoreML提示MyModel不在作用域
修复
Cannot find 'MyModel' in scope 编译错误(CoreML + React Native 原生模块场景) 这个报错的本质是Xcode自动生成的CoreML模型类,没有被你当前编写VideoProcessor的编译Target纳入作用域,按以下步骤逐一排查:
- 核对模型类名与Target归属
选中项目中的MyModel.mlmodel文件,打开Xcode右侧的File Inspector面板:- 查看「Target Membership」列表,必须勾选
VideoProcessor所在的编译Target。注意React Native的原生代码如果是通过Pod集成的,对应的Target是你Podspec描述的模块Target,只勾选主App Target会导致Pod内的代码访问不到模型类。 - 查看面板中「Class」区块显示的自动生成类名,不要自己臆测类名:如果模型文件名包含横杠、空格、版本号,Xcode会自动转成合法Swift类名,比如
my-model_v2.mlmodel生成的类名是My_model_v2,和你写的MyModel不一致就会报找不到的错误。
- 查看「Target Membership」列表,必须勾选
- 绕开自动生成类的作用域限制(RN模块最稳妥方案)
RN原生模块作为独立编译Target时,默认internal权限的自动生成模型类无法跨Target访问,直接通过Bundle路径加载编译后的模型文件即可完全绕开这个问题,不需要依赖Xcode生成的类:
注意// 替换你原来的model初始化代码 guard let modelPath = Bundle.main.url(forResource: "MyModel", withExtension: "mlmodelc") else { fatalError("模型未打包进App Bundle,检查Target Membership配置") } let mlModel = try MLModel(contentsOf: modelPath, configuration: MLModelConfiguration()) let model = try VNCoreMLModel(for: mlModel).mlmodel文件在编译阶段会被Xcode编译为优化后的.mlmodelc格式存放在App Bundle中,用这种方式加载不会有类名找不到的问题。 - 清理编译缓存
Xcode经常出现CoreML类生成不及时的缓存问题,按顺序操作后重新编译:- 按下
Shift + Command + K清空当前工程的Build产物 - 关闭Xcode,删除
~/Library/Developer/Xcode/DerivedData目录下对应项目的缓存文件夹 - 项目根目录执行
pod install重新关联依赖
- 按下
现有代码的其他已知问题(不修复会导致功能异常)
- 当前逐帧抽帧+推理是异步流程,你在
for循环执行完后立刻销毁generator、触发回调,此时大部分帧还没完成抽帧和推理,返回的结果是空的。需要用DispatchGroup监听所有帧的处理完成事件,全部跑完再触发callback。 AVAssetImageGenerator的appliesPreferredTrackTransform属性建议设为true,否则竖拍视频带的旋转元数据不会生效,抽出来的帧方向错误,会直接导致模型推理结果失效。CMTimeMakeWithSeconds的preferredTimescale传600是合理值,代表时间轴精度为1/600秒,足够覆盖30/60fps的普通视频抽帧需求,不需要修改。- 所有
try!强制解包的逻辑建议替换为do-catch错误捕获,避免模型加载失败、JSON编码失败时直接触发App崩溃。
内容的提问来源于stack exchange,提问作者Brendan O'Brien
相关产品推荐
相关产品推荐

