【问题标题】:SwiftUI and functions - Cannot find 'viewContext' in scopeSwiftUI 和函数 - 在范围内找不到“viewContext”
【发布时间】:2021-09-14 09:53:28
【问题描述】:

我想将我的函数与 SwiftUI 视图分开。我有这个功能:

import Foundation
import CoreData

func deleteAll() {
    let fetchRequestItems: NSFetchRequest<NSFetchRequestResult> = Item.fetchRequest()
    let deleteRequestItems = NSBatchDeleteRequest(fetchRequest: fetchRequestItems)
    
    do {
        try viewContext.save()
        try viewContext.execute(deleteRequestItems)
        viewContext.reset()
    } catch let error as NSError {
        print(error)
    }
}

我在 viewContext 的 3 行上遇到错误:

在范围内找不到“viewContext”

当它在 SwiftUI 视图中时,同样的功能也可以工作。但是视图的 viewContext 是这样注入的:

ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)

所以问题是: 如何在单独的 Swift 文件中的函数内部注入/使用 Core Data Context (viewContext)?

编辑: Persistence.swift 来自 SwiftUI 2.0 模板,如下所示:

import CoreData

struct PersistenceController {
    static let shared = PersistenceController()

    static var preview: PersistenceController = {
        let result = PersistenceController(inMemory: true)
        let viewContext = result.container.viewContext
        for _ in 0..<10 {
            let newItem = Item(context: viewContext)
            newItem.timestamp = Date()
        }
        
        do {
            try viewContext.save()
        } catch {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }
        return result
    }()

    let container: NSPersistentCloudKitContainer

    init(inMemory: Bool = false) {
        container = NSPersistentCloudKitContainer(name: "Moneto")
        if inMemory {
            container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
        }
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

                /*
                Typical reasons for an error here include:
                * The parent directory does not exist, cannot be created, or disallows writing.
                * The persistent store is not accessible, due to permissions or data protection when the device is locked.
                * The device is out of space.
                * The store could not be migrated to the current model version.
                Check the error message to determine what the actual problem was.
                */
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
    }
}

【问题讨论】:

  • deleteAll(context: NSManagedObjectContext) { … }
  • 有效!谢谢,@JoakimDanielson :) 请您将其作为答案发送,这样我可以接受吗? 2个小cmets。 1. 就我而言,它是deleteAll(viewContext: NSManagedObjectContext) { … }。 2.运行函数时,应该使用deleteAll(viewContext: viewContext)

标签: ios swift function core-data swiftui


【解决方案1】:

您应该将托管上下文注入到您的函数中

func deleteAll(viewContext: NSManagedObjectContext) {
    //…
}

这还为您提供了一个优势,即如果您正在使用背景或子上下文,您可以选择从哪个上下文中删除

【讨论】:

    【解决方案2】:

    在你的视图中添加这个变量

    @Environment(\.managedObjectContext) var viewContext
    

    【讨论】:

    • 谢谢,但我有它的意见。准确地说,我有:@Environment(\.managedObjectContext) private var viewContext。但即使没有private,它也不起作用。请注意,我的函数在单独的文件中。不在 SwiftUI 视图中。这是一个单独的函数的 Swift 文件。
    • 没有。这样不好。请将您的功能移动到您的视图或视图模型。
    • 所以我不能将它们保存在单独的文件中?如果您有很多功能,那么将视图分解为更小部分的正确方法是什么?
    • 使用扩展。创建您的视图的扩展名,例如 extension ContentView {...} 并将此扩展名添加到单独的文件中。全局函数不是一个好主意。
    • 您还可以从 Persistence.swift 文件中将您的视图上下文设为静态,然后在任何地方使用它。
    猜你喜欢
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    • 2023-01-26
    • 1970-01-01
    • 2020-11-23
    • 2021-06-18
    • 2021-01-15
    • 1970-01-01
    相关资源
    最近更新 更多