কোরডেটা এবং সুইফটুআই: পরিবেশে প্রসঙ্গটি একটি ধ্রুবক স্টোর সমন্বয়কের সাথে সংযুক্ত নয়


10

আমি হোমওয়ার্ক ম্যানেজিং অ্যাপ্লিকেশন তৈরি করে নিজেকে কোর ডেটা শেখানোর চেষ্টা করছি। আমার কোডটি দুর্দান্ত তৈরি করে এবং তালিকায় নতুন অ্যাসাইনমেন্ট যোগ করার চেষ্টা না করা পর্যন্ত অ্যাপ্লিকেশনটি ঠিক আছে। আমি এই ভুল পান Thread 1: EXC_BREAKPOINT (code=1, subcode=0x1c25719e8)নিম্নলিখিত লাইনে: ForEach(courses, id: \.self) { course in। কনসোল এই ত্রুটি আছে: Context in environment is not connected to a persistent store coordinator: <NSManagedObjectContext: 0x2823cb3a0>

আমি কোর ডেটা সম্পর্কে খুব কম জানি এবং সমস্যাটি কী হতে পারে তার ক্ষতিতে। আমি ডেটা মডেলে "অ্যাসাইনমেন্ট" এবং "কোর্স" সত্ত্বা স্থাপন করেছি, যেখানে অ্যাসাইনমেন্টের সাথে কোর্সের একাধিক সম্পর্ক রয়েছে। প্রতিটি অ্যাসাইনমেন্ট একটি নির্দিষ্ট কোর্সের অধীনে শ্রেণিবদ্ধ করা হবে।

এই দেখার জন্য কোডটি যা তালিকায় একটি নতুন অ্যাসাইনমেন্ট যুক্ত করে:

    struct NewAssignmentView: View {

    @Environment(\.presentationMode) var presentationMode
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Course.entity(), sortDescriptors: []) var courses: FetchedResults<Course>

    @State var name = ""
    @State var hasDueDate = false
    @State var dueDate = Date()
    @State var course = Course()

    var body: some View {
        NavigationView {
            Form {
                TextField("Assignment Name", text: $name)
                Section {
                    Picker("Course", selection: $course) {
                        ForEach(courses, id: \.self) { course in
                            Text("\(course.name ?? "")").foregroundColor(course.color)
                        }
                    }
                }
                Section {
                    Toggle(isOn: $hasDueDate.animation()) {
                        Text("Due Date")
                    }
                    if hasDueDate {
                        DatePicker(selection: $dueDate, displayedComponents: .date, label: { Text("Set Date:") })
                    }
                }
            }
            .navigationBarTitle("New Assignment", displayMode: .inline)
            .navigationBarItems(leading: Button(action: {
                self.presentationMode.wrappedValue.dismiss()
            }, label: { Text("Cancel") }),
                                trailing: Button(action: {
                                    let newAssignment = Assignment(context: self.moc)
                                    newAssignment.name = self.name
                                    newAssignment.hasDueDate = self.hasDueDate
                                    newAssignment.dueDate = self.dueDate
                                    newAssignment.statusString = Status.incomplete.rawValue
                                    newAssignment.course = self.course
                                    self.presentationMode.wrappedValue.dismiss()
                                }, label: { Text("Add").bold() }))
        }
    }
}

সম্পাদনা: অ্যাপডেলিগেটের কোডটি যা অবিরাম ধারক সেট আপ করে:

lazy var persistentContainer: NSPersistentCloudKitContainer = {
    let container = NSPersistentCloudKitContainer(name: "test")
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
    return container
}()

এবং সিনডেলিগেটের কোড যা পরিবেশ স্থাপন করে:

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
    // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
    // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

    // Get the managed object context from the shared persistent container.
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    // Create the SwiftUI view and set the context as the value for the managedObjectContext environment keyPath.
    // Add `@Environment(\.managedObjectContext)` in the views that will need the context.
    let contentView = ContentView().environment(\.managedObjectContext, context)

    // Use a UIHostingController as window root view controller.
    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = UIHostingController(rootView: contentView)
        self.window = window
        window.makeKeyAndVisible()
    }
}

আপনি পরিবেশে পরিচালিত অবজেক্ট প্রসঙ্গটি কোথায় যুক্ত করবেন? কীভাবে সেই পরিচালিত অবজেক্টের প্রসঙ্গ তৈরি হয়? দেখে মনে হচ্ছে আপনি এটি একটি
ধ্রুবক

আমি কোডটি যুক্ত করেছি যেখানে আমি আপনার মূল পোস্টে পরিবেশের সাথে মোক যোগ করব।
কেভিন ওলম্যাটস

@ কেভিনআলমেটস আমার উত্তরটি সাহায্য করেছিল?
ফুলভিও

আপনি পরিবেশের মাধ্যমে একটি প্রসঙ্গ নিযুক্ত করেছেন .environment(\.managedObjectContext, viewContext)
কিনা তা পরীক্ষা করুন

@ onmyway133 এটি সঠিক উত্তর
কেভিন ওলমেট

উত্তর:


8

আপনি আসলে প্রসঙ্গটি সংরক্ষণ করছেন না। আপনি নিম্নলিখিত সম্পাদন করা উচিত:

let newAssignment = Assignment(context: self.moc)
newAssignment.name = self.name
newAssignment.hasDueDate = self.hasDueDate
newAssignment.dueDate = self.dueDate
newAssignment.statusString = Status.incomplete.rawValue
newAssignment.course = self.course

do {
    try self.moc.save()
} catch {
    print(error)
}

এছাড়াও আপনার @FetchRequest(...)এই মত দেখতে পারে:

@FetchRequest(fetchRequest: CourseItem.getCourseItems()) var courses: FetchedResults<CourseItem>

নিম্নলিখিতগুলির মতো CourseItemহ্যান্ডেল করতে আপনি আপনার ক্লাসটি সংশোধন করতে পারেন sortDescriptors:

public class CourseItem: NSManagedObject, Identifiable {
    @NSManaged public var name: String?
    @NSManaged public var dueDate: Date?
    // ...etc
}

extension CourseItem {
    static func getCourseItems() -> NSFetchRequest<CourseItem> {
        let request: NSFetchRequest<CourseItem> = CourseItem.fetchRequest() as! NSFetchRequest<CourseItem>

        let sortDescriptor = NSSortDescriptor(key: "dueDate", ascending: true)

        request.sortDescriptors = [sortDescriptor]

        return request
    }
}

তারপরে আপনি ForEach(...)নীচের মত আপনার সংশোধন করতে পারবেন এবং পাশাপাশি আইটেমগুলি মুছতে খুব সহজে পরিচালনা করতে পারবেন:

ForEach(self.courses) { course in
    // ...
}.onDelete { indexSet in
    let deleteItem = self.courses[indexSet.first!]
    self.moc.delete(deleteItem)

    do {
        try self.moc.save()
    } catch {
        print(error)
    }
}

আপনি যে বিষয়টি নিশ্চিত করতে চান তা হ'ল "শ্রেণীর নাম" "কোর্স আইটেম" এ সেট করা হয়েছে, যা CourseItemআমরা আগে তৈরি ক্লাসের সাথে মেলে ।

কেবলমাত্র ক্লিক সত্ত্বা আপনার .xcdatamodeId(তত্সহ নিম্নলিখিত ফাইল এবং সবকিছু সেট মডিউল "বর্তমান পণ্য মডিউল" এবং Codegen "ম্যানুয়াল / কোনোটিই নয়" থেকে):

এখানে চিত্র বর্ণনা লিখুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.