วิธีดำเนินการ Core Data NSFetchRequest ในวิธีการเรียน?

ฉันมีไฟล์ AppName.xcdatamodeld โดยมี Category ใน Entities ใน Category ฉันเพิ่มบันทึกจาก SwiftUI ได้สำเร็จและดึงข้อมูลเหล่านั้นใน View ได้สำเร็จดังนี้:

import SwiftUI
import CoreData

struct CategoriesList: View {
    @Environment(\.managedObjectContext) var moc
    
    var fetchRequest: FetchRequest<CountdownCategory>
    var countdownCategories: FetchedResults<CountdownCategory> {
        fetchRequest.wrappedValue
    }
    
    var body: some View {
        ForEach(countdownCategories, id: \.self) { countdownCategory in
            Text(countdownCategory.title ?? "Category")
        }
    }
    
    init() {
        fetchRequest = FetchRequest<CountdownCategory>(entity: CountdownCategory.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \CountdownCategory.dateAdded, ascending: false)])
    }
}

ตอนนี้ฉันต้องดำเนินการค้นหาเดียวกันในตำแหน่งอื่นของโปรแกรม - ไม่ใช่ในมุมมอง SwiftUI แต่ในวิธีการในคลาส:

import Foundation
import CoreData

class Categories {
    func getCategories() {
        let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
        let categoriesFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "CountdownCategory")
         
        do {
            let categoriesFetch = try moc.fetch(categoriesFetch) as! [CountdownCategory]
        } catch {
            fatalError("Failed to fetch categories: \(error)")
        }
        
        // etc.
    }
}

ฉันค้นหาโค้ดตัวอย่างในเอกสารประกอบ Core Data อย่างเป็นทางการ แต่เมื่อฉันพยายามดำเนินการนี้ ฉันได้รับข้อผิดพลาด:

*** การยกเลิกแอปเนื่องจากข้อยกเว้นที่ไม่ได้ตรวจสอบ 'NSInvalidArgumentException' เหตุผล: '+entityForName: nil ไม่ใช่ NSPersistentStoreCoordinator ทางกฎหมายสำหรับการค้นหาชื่อเอนทิตี 'CountdownCategory'

ขอขอบคุณสำหรับความช่วยเหลือในการแก้ไขข้อผิดพลาดนั้น เป้าหมายของฉันคือการรับข้อมูลจาก Core Data จาก CountdownCategory ในวิธีนี้ (สวิฟท์ 5.2)

UPD #1: เมื่อฉันใช้ let categoriesFetch = CountdownCategory.fetchRequest() ฉันได้รับข้อผิดพลาด:

การใช้ 'fetchRequest()' อย่างคลุมเครือ

UPD #2: เมื่อฉันใช้ let categoriesFetch: NSFetchRequest<CountdownCategory> = CountdownCategory.fetchRequest() ฉันไม่ประสบปัญหาขัดข้อง แต่ฉันจะได้รับข้อมูลได้อย่างไร


person Igor R.    schedule 26.06.2020    source แหล่งที่มา


คำตอบ (1)


let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)

คุณกำลังสร้างบริบทออบเจ็กต์ที่ได้รับการจัดการใหม่ล่าสุดที่นี่ โดยไม่มีการสนับสนุนร้านค้าหรือโมเดลถาวร นั่นไม่ใช่วิธีที่ถูกต้องที่จะทำ คุณต้องใช้บริบทเดียวกันกับที่คุณส่งผ่านไปยังออบเจ็กต์สภาพแวดล้อม SwiftUI ของคุณไม่ว่าจะมาจากไหน

คุณบอกว่าตัวแทนแอปมี NSPersistentContainer ดังนั้นฉันเดาว่าคุณใช้เทมเพลตแอป SwiftUI / Core Data ในกรณีนั้น คุณจะต้องแทนที่บรรทัดโค้ดด้านบน (let moc = ...) ด้วยข้อความดังนี้:

let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

หากคุณใช้เทมเพลต คุณสามารถดูใน SceneDelegate.swift และดูว่าบริบทถูกแทรกลงในสภาพแวดล้อม SwiftUI ที่ใดโดยใช้โค้ดที่คล้ายกัน

person jrturton    schedule 26.06.2020
comment
ฉันส่งวัตถุสภาพแวดล้อมไปยัง View ดังนี้: CategoriesList().environment(\.managedObjectContext, moc) แต่ฉันพยายามประกาศ/ใช้ในวิธีการ - person Igor R.; 26.06.2020
comment
moc ในโค้ดของความคิดเห็นของคุณมาจากไหน นั่นคือตัวอย่างที่คุณต้องใช้ในวิธีการเรียน - person jrturton; 26.06.2020
comment
มันมาจาก @Environment(\.managedObjectContext) var moc ในการดูก่อน var body: some View {... - person Igor R.; 26.06.2020
comment
คุณต้องติดตามมันไปเรื่อย ๆ จนกว่าคุณจะพบว่ามันถูกสร้างขึ้นที่ไหนตั้งแต่แรก แอปของคุณมี NSPersistentContainer อยู่ที่ใดหรือไม่ - person jrturton; 26.06.2020
comment
ใช่ ใน AppDelegate.swift ในส่วน Core Data Stack let container = NSPersistentCloudKitContainer(name: "MyTitle") - person Igor R.; 26.06.2020