如何在“AppDelegate”而不是“App”中定义 SwiftData modelContainer?

问题描述 投票:0回答:2

我有一个使用 SwiftData 的工作项目,它完全是用 UIViews 构建的。本质上,用户将点击 UIView 上的答案,然后向我的 SwiftData 输出添加一行。这按预期工作。我想将此数据移植到一个新项目中,在该项目中添加了 AR 功能,然后点击环境中的 ImageAnchors 打开现有视图。我无法弄清楚如何在这个新项目中定义 modelContainer。我原来的应用程序中没有 UIViewController,但我的新 AR 应用程序中有一个,这让我的事情变得更加复杂。

对于我现有项目的“应用程序”,我有:

应用程序:

import SwiftUI
import SwiftData

@main
struct QuizTestApp: App {
    var body: some Scene {
        WindowGroup {
            
            QuizView()
        }
        .modelContainer(for: SwiftDataController.self)
    }
}

请注意,“.modelContainer(for: SwiftDataController.self)”这行本质上是我试图在 AppDelegate 中设置的内容。

型号:“SwiftDataController”

import Foundation
import SwiftData

@Model
class SwiftDataController: Identifiable {
    
    var module: Int
    var correct: Bool
    var dateTaken: Date
    
    init(module: Int, correct: Bool, dateTaken: Date = .now) {
        self.module = module
        self.correct = correct
        self.dateTaken = .now
    }
}

数据通过 UIView 中的 addItem 方法添加,然后显示在我可以通过按钮访问的单独视图的列表中。

这是我的新项目的AppDelegate:

import UIKit
import SwiftData

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

我对 Swift 比较陌生,因此任何有关如何处理此问题或绕过此拦截器的指导将不胜感激。非常感谢!

我不确定是否可以在同一个项目中拥有 App 和 AppDelegate,但我尝试了 Google 建议的其他一些方法,在 AppDelegate 中声明 modelContainer,但我的项目在运行时崩溃了。

appdelegate swiftdata
2个回答
1
投票

我喜欢将 SwiftData 代码隔离到“管理器”中。

以下是如何为我的模型站创建容器。

public struct SwiftDataManager {
    
    public static let instance = SwiftDataManager()
    
    public var container: ModelContainer
    
    init() {
        
        let configuration = ModelConfiguration(for: Station.self,
                                               isStoredInMemoryOnly: true)
        
        let schema = Schema([Station.self])
        
        do {
            container = try ModelContainer(for: schema,
                                           configurations: [configuration])
        } catch {

等等


0
投票

看起来您正在尝试将具有应用程序、场景和视图的新最佳实践架构与老式的应用程序/AppDelegate 架构混合在一起。这样做是可能的,但它很混乱且令人困惑。你原来的项目真的使用了

UIView
吗?或者它是用 SwiftUI 编写的,使用它的
View
类?

我建议您跳过

AppDelegate
实现,完全在 SwiftUI 中构建应用程序(因为 Swift Data 需要 SwiftUI),并遵循 @gene-de-lisa 将 Swift Data 代码隔离给管理器的建议。

ARKit 与 SwiftUI 配合得很好,我认为没有理由在你的项目中与 UIKit 或 AppDelegate 有任何关系。

© www.soinside.com 2019 - 2024. All rights reserved.