You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 09:48:53