Swift CoreData Сохранить атрибут с типом пользовательского класса - PullRequest
0 голосов
/ 26 сентября 2019

Я новичок в использовании CoreData в качестве базы данных для хранения данных пользователей для поддержки автономного использования приложений.Я настроил модель данных для своих объектов, и некоторые атрибуты должны быть сохранены в типе других моих классов объектов.Тем не менее, он, кажется, успешно сохранен, но возвращает nil, когда я пытался получить результаты из базы данных.Я также заглянул в файл базы данных SQLite, чтобы увидеть, что случилось с полем, которое было сохранено в CoreData, и дало мне nil в качестве результатов (а возвращаемый тип был найден Optional(Any)), и обнаружил, что атрибут данных былхранится в типе BLOB.

Результаты хранятся в SQLite:

SQLite Database

Первоначально мое приложение можно было использовать толькокогда сеть доступна, но я пытаюсь включить поддержку автономного доступа.Тем не менее, я придерживаюсь проблем и не знаю, как их решить, и даже я не уверен, правильно ли я поступил.

Один из примеров моих пользовательских классов объектов StudentMarkList:

import Foundation
import UIKit
import CoreData

@objc(StudentMarkList)

class StudentMarkList: NSObject {
    var id = Int() // Student ID in DB (Primary Key)
    var paperId = String() // Paper ID which the student attended
    var studentClass = String() // Student class
    var totalMark = Int() // Total mark of the attended paper
    var allMarked = Bool() // Flag whether student's paper is all marked
    var markList = [MarkList]() // Array of marks for each question <- Custom object class of defining the structure of each question's mark

    override init() {
        super.init()
    }

    init(id:Int, paperId:String, studentClass:String, totalMark:Int, allMarked:Bool, markList:[MarkList]){
        self.id = id
        self.paperId = paperId
        self.studentClass = studentClass
        self.totalMark = totalMark
        self.allMarked = allMarked
        self.markList = markList
    }

    func save() {
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
            return
        }

        let managedContext = appDelegate.persistentContainer.viewContext
        managedContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy

        let entity = NSEntityDescription.entity(forEntityName: "StudentMarkList", in: managedContext)!
        let studentMarkList = NSManagedObject(entity: entity, insertInto: managedContext)

        studentMarkList.setValue(self.id, forKey: "id")
        studentMarkList.setValue(self.paperId, forKey: "paperId")
        studentMarkList.setValue(self.studentClass, forKey: "studentClass")
        studentMarkList.setValue(self.totalMark, forKey: "totalMark")
        studentMarkList.setValue(self.allMarked, forKey: "allMarked")
        studentMarkList.setValue(self.markList, forKey: "markList")

        if managedContext.hasChanges {
            do {
                try managedContext.save()
            } catch let error as NSError {
                print("Could not save. \(error), \(error.userInfo)")
            }
        }
    }
}

Модель StudentMarkList:

StudentMarkList model

Соответствующий класс пользовательских объектов MarkList:

import Foundation
import UIKit
import CoreData

@objc(MarkList)

class MarkList: NSObject, NSCoding {
    func encode(with aCoder: NSCoder) {
        aCoder.encode(questionId, forKey: "questionId")
        aCoder.encode(questionNo, forKey: "questionNo")
        aCoder.encode(questionMark, forKey: "questionMark")
    }

    required init?(coder aDecoder: NSCoder) {
        guard let questionId = aDecoder.decodeObject(forKey: "questionId") as? Int,
            let questionNo = aDecoder.decodeObject(forKey: "questionNo") as? Int,
            let questionMark = aDecoder.decodeObject(forKey: "questionMark") as? String else {
                return nil
        }
        self.questionId = questionId
        self.questionNo = questionNo
        self.questionMark = questionMark
    }

    var questionId = Int()
    var questionNo = Int()
    var questionMark = String()

    override init() {
        super.init()
    }

    init(questionId: Int, questionNo: Int, questionMark: String) {
        self.questionId = questionId
        self.questionNo = questionNo
        self.questionMark = questionMark
    }

    func save() {
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
            return
        }

        let managedContext = appDelegate.persistentContainer.viewContext
        managedContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy

        let entity = NSEntityDescription.entity(forEntityName: "MarkList", in: managedContext)!
        let markList = NSManagedObject(entity: entity, insertInto: managedContext)

        markList.setValue(self.questionId, forKey: "questionId")
        markList.setValue(self.questionNo, forKey: "questionNo")
        markList.setValue(self.questionMark, forKey: "questionMark")

        if managedContext.hasChanges {
            do {
                try managedContext.save()
            } catch let error as NSError {
                print("Could not save. \(error), \(error.userInfo)")
            }
        }
    }
}

Модель MarkList:

MarkList model

Функция save() используется для сохранения экземпляра в CoreData в качестве соответствующегокласс объекта.

Надеюсь, кто-нибудь может мне помочь или разъяснить мне концепции использования CoreData.Спасибо!

1 Ответ

0 голосов
/ 26 сентября 2019

Чтобы получить пользовательский класс как атрибут вашей сущности CoreData.Каждый класс должен рассматриваться как отдельная сущность, а связывание данных должно осуществляться через отношения

. Вы должны создать новую сущность для marklist, StudentMarkList будет вашей родительской сущностью.

enter image description here

Просто добавьте отношение marklist к studentMarkList, выберите свой объект StudentMarkList и создайте отношение, как показано на рисунке.Не беспокойтесь об обратном, следуйте следующему шагу, это будет ясно.

enter image description here

Теперь выберите сущность Marklist и добавьте связь, как показано ниже

enter image description here

Пожалуйста, не забудьте изменить код класса, чтобы использовать руководство

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...