Swift Playground中SwiftUI连接CoreML报SleepCalculator找不到作用域问题
报错原因
SleepCalculator不是CoreML或SwiftUI框架自带的系统类,它是开发者将训练好的CoreML模型文件(后缀为.mlmodel,命名为SleepCalculator)导入项目后,Xcode自动生成的模型交互类,作用是加载训练好的睡眠预测模型、接收输入参数输出预测结果。- 出现
cannot find 'SleepCalculator' in scope报错的核心原因是你没有将对应的SleepCalculator.mlmodel文件导入到当前Swift Playground项目中,Xcode没有自动生成对应的类代码,自然无法识别该类型。 - 除了模型缺失的核心问题,你的代码还存在多处语法、逻辑错误,同样会导致编译失败或运行结果异常。
修复方案
1. 导入对应CoreML模型文件
- 提前获取betterRest项目配套的
SleepCalculator.mlmodel训练好的模型文件,将文件直接拖拽到Swift Playground的文件导航栏内。 - 如果使用的是Xcode内置的Playground环境,选中导入后的mlmodel文件,在右侧文件检查器的
Target Membership栏目下,勾选当前Playground对应的target,确保Xcode能识别到该文件并自动生成Swift接口类,完成后找不到类型的报错会直接消失。
2. 修正代码中存在的其他错误
- 删除ContentView结构体开头的
Let model = SleepCalculator():这行代码首字母Let大写违反Swift语法(Swift关键字严格区分大小写),且你在计算方法内会重新初始化模型,属于冗余代码直接删除即可。 - 修正预测方法的拼写错误:Xcode自动生成的模型预测方法名为
prediction,你代码中写为predication属于拼写错误,调用时会触发找不到方法的报错。 - 修正时间转秒的逻辑错误:分钟转秒的计算倍率为60,你代码中写为
(components.minute ?? 0) * 60 * 60,和小时转秒的倍率一致,会导致传入模型的唤醒时间参数完全错误,正确写法为let minute = (components.minute ?? 0) * 60。 - 修正弹窗内容的类型错误:计算得到的
sleepTime是Date类型,不能直接赋值给字符串类型的alertMessage,需要通过日期格式化工具转换为仅显示时分的字符串。 - 删除重复的弹窗修饰符:你在Stepper控件和VStack容器上各挂载了一个
.alert修饰符,会导致弹窗重复触发,直接删除Stepper上的那个弹窗修饰符即可。 - (可选规范修正)你代码中表示咖啡摄入量的变量名
coffeAmount存在拼写错误,正确拼写为coffeeAmount,该问题不影响运行,仅为命名规范问题。
修正后可正常运行的完整代码
import CoreML import SwiftUI struct ContentView: View { @State private var wakeUp = Date.now @State private var sleepAmount = 8.0 @State private var coffeeAmount = 1 @State private var alertTitle = "" @State private var alertMessage = "" @State private var showingAlert = false var body: some View { NavigationView { VStack { Text("when do u want to wake up") .font(.headline) DatePicker("please enter a time", selection: $wakeUp, displayedComponents: .hourAndMinute) .labelsHidden() Text("desired amount of sleep") .font(.headline) Stepper("\(sleepAmount.formatted()) hours", value: $sleepAmount, in: 4...12,step: 0.25) Text("daily coffee intake") .font(.headline) Stepper(coffeeAmount == 1 ? "1 cup" : "\(coffeeAmount) cups", value: $coffeeAmount, in: 1...20) } .navigationTitle("betterRest") .toolbar { Button("calculate", action: calculateBedtime) } .alert(alertTitle, isPresented: $showingAlert) { Button("ok") { } } message: { Text(alertMessage) } } } func calculateBedtime() { do { let config = MLModelConfiguration() let model = try SleepCalculator(configuration: config) let components = Calendar.current.dateComponents([.hour, .minute], from: wakeUp) let hour = (components.hour ?? 0) * 60 * 60 let minute = (components.minute ?? 0) * 60 let prediction = try model.prediction(wake: Double(hour + minute), estimatedSleep: sleepAmount, coffee: Double(coffeeAmount)) let sleepTime = wakeUp - prediction.actualSleep alertTitle = "Your ideal bedtime is…" let formatter = DateFormatter() formatter.timeStyle = .short alertMessage = formatter.string(from: sleepTime) } catch { alertTitle = "error" alertMessage = "sorry, there was a problem calculating your bedtime." } showingAlert = true } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
内容的提问来源于stack exchange,提问作者x3kss
相关产品推荐
相关产品推荐

