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

Swift开发儿童屏蔽应用报错:MyModel不在作用域内求助

问题解决:MyModel找不到的原因及代码修复

核心原因

你代码里完全没定义MyModel这个类型,Swift编译器不知道这个东西是什么,所以会提示找不到。YouTube教程里肯定有这个模型的实现,你漏写了。另外你的代码结构有严重问题,很多代码放错了位置,这也会导致作用域混乱。

分步修复

1. 补上MyModel的定义

在你的文件顶部(Testing_SwiftUIApp结构体外面)添加这个模型类,它用来保存Family Controls的应用选择:

import FamilyControls

class MyModel: ObservableObject {
    @Published var selectionToDiscourage = FamilyActivitySelection()
}

2. 彻底修复代码结构

你把类、函数、变量都塞到App的body里,这完全不符合SwiftUI语法,body只能返回Scene内容。下面是修正后的完整代码:

import Foundation
import FamilyControls
import DeviceActivity
import ManagedSettings
import SwiftUI

// 补上MyModel定义
class MyModel: ObservableObject {
    @Published var selectionToDiscourage = FamilyActivitySelection()
}

extension DeviceActivityName {
    static let daily = Self("daily")
}

// 把MyMonitor移到顶层,不能放在body里
class MyMonitor: DeviceActivityMonitor {
    let store = ManagedSettingsStore()
    // 注入MyModel,保证监控器和UI用的是同一套数据
    private let model: MyModel
    
    init(model: MyModel) {
        self.model = model
        super.init()
    }
    
    override func intervalDidStart(for activity: DeviceActivityName) {
        super.intervalDidStart(for: activity) // 直接调用父类方法,不需要额外包装函数
        let applications = model.selectionToDiscourage.applications
        store.shield.applications = applications?.isEmpty == true ? nil : applications
    }
    
    override func intervalDidEnd(for activity: DeviceActivityName) {
        super.intervalDidEnd(for: activity)
        store.shield.applications = nil
    }
}

struct Testing_SwiftUIApp: App {
    // 在App层初始化全局唯一的MyModel实例
    @StateObject private var model = MyModel()
    private let monitor: MyMonitor
    
    init() {
        // 初始化监控器并传入model
        self.monitor = MyMonitor(model: model)
        // 配置监控计划并启动,处理可能的错误
        let schedule = DeviceActivitySchedule(
            intervalStart: DateComponents(hour: 0, minute: 0),
            intervalEnd: DateComponents(hour:23, minute: 59),
            repeats: true
        )
        let center = DeviceActivityCenter()
        do {
            try center.startMonitoring(.daily, during: schedule)
        } catch {
            print("启动监控失败:\(error.localizedDescription)")
        }
    }
    
    var body: some Scene {
        WindowGroup {
            // 将model传递给ContentView使用
            ContentView(model: model)
        }
    }
}

// 把UI相关代码移到ContentView中,符合SwiftUI结构规范
struct ContentView: View {
    @ObservedObject var model: MyModel
    @State private var isPresented = false
    
    var body: some View {
        Button ("Select Apps to Discourage"){
            isPresented = true
        }
        .familyActivityPicker(isPresented: $isPresented,
                              selection: $model.selectionToDiscourage)
    }
}

关键调整说明

  • MyModel作为ObservableObject,实现跨组件(UI、监控器)的状态共享,避免重复实例化导致数据不一致。
  • MyMonitor通过初始化注入MyModel,确保能拿到用户选择的最新应用列表。
  • 启动监控的代码移到App的初始化方法中,并处理了try的错误(Swift要求必须处理抛出的错误)。
  • 所有UI代码归到ContentView,符合SwiftUI的分层结构设计。

内容的提问来源于stack exchange,提问作者CabooseThePsychonaut

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 13:05:44