How to Store and Fetch Json Model data to Coredata

2019-06-12 14:27发布

问题:

I have used coredata long back. But, I know basics of coredata for storing data and fetching.

But, Presently I am working with Swift language.

I have local json file and I am doing parsing that by decoder and displaying that data in tableview.

let path = Bundle.main.path(forResource: "file", ofType: "json")

do {
    let data = try Data(contentsOf: URL(fileURLWithPath: path ?? ""), options: .mappedIfSafe)
    let decoder = JSONDecoder()
    do {
        quData = try decoder.decode(quData.self, from: data)
        DispatchQueue.main.async {
            self.myTableView.reloadData()
        }
    } catch {
        print("Json decoder error")
    }
} catch {
    print(LocalizedError.self)
}

For that I have created model class based on the key values of json.

But, Now I have to store that data to Coredata and Fetch back, Need to show in same tableview.

But, I am getting confusion how many key values should I need to create.

My model class is :

class QuData: Codable {
    let qu: Qu

    init(qu: Qu) {
        self.qu = qu
    }
}

class Qu: Codable {
    let music: Music
    let dance: dance

    init(music: Music, dance: dance) {
        self.music = music
        self.dance = dance
    }
}

class Maths: Codable {
    let q1, q2: Q1

    init(q1: Q1, q2: Q1) {
        self.q1 = q1
        self.q2 = q2
    }
}

class Q1: Codable {
    let query: String
    let options: [String]
    let answer: String
    let q1Optional: Bool

    enum CodingKeys: String, CodingKey {
        case query, options, answer
        case q1Optional = "optional"
    }

    init(question: String, options: [String], answer: String, q1Optional: Bool) {
        self.query = query
        self.options = options
        self.answer = answer
        self.q1Optional = q1Optional
    }
}

class Sport: Codable {
    let q1: Q1

    init(q1: Q1) {
        self.q1 = q1
    }
}

And my JSON data is

{
    "qu": {
        "music": {
            "q1": {
                “query”: “What is your name?”,
                "options": [
                    “Sony”,
                    “Samsung”,
                    “Apple”,
                    “MI”
                ],
                "answer": “Apple”,
                "optional": true

            }
        },
        “dance”: {
            "q1": {
                "question": "5 + 1 = ?",
                "options": [
                    “8”,
                    “9”,
                    “6”,
                    “23”
                ],
                "answer": “23”,
                "optional": false
            },
            "q2": {
                "question": "12 - 4 = ?",
                "options": [
                    “5”,
                    “4”,
                    “9”,
                    “6”
                ],
                "answer": "4",
                "optional": false
            }
        }
    }
}

How to store these data to Coredata and fetching, Showing in tableview..

And, The two categories (music,dance) in json data, I have to show "Music" data in 1st section and "Dance" data in section tableview.

I am fully struck, how to create this kind json structure in Entity with attributes and fetching them using same model class (Which already created for local json file parsing).

Can anyone suggest me to move on further?

回答1:

My suggestion is to use one entity.

In Core Data you can filter records very efficiently, so add a type attribute representing music, dance etc. You can even add a computed property to map the type attribute to an enum. The options attribute is declared as flat string. Use another computed property to map the flat string to an array and vice versa.

class Question : NSManagedObject {

    @NSManaged var type: String
    @NSManaged var question: String
    @NSManaged var answer: String
    @NSManaged var options: String
    @NSManaged var optional: Bool

    enum QuestionType : String {
        case music, dance
    }

    var questionType : QuestionType {
        get { return QuestionType(rawValue: type)! }
        set { type = newValue.rawValue }
    }

    var questionOptions : [String] {
        get { return options.components(separatedBy: ", ") }
        set { options = newValue.joined(separator: ", ") }
    }

Alternatively use one entity per type and relationships for the questions

class Music : NSManagedObject {

    @NSManaged var questions: Set<Question>

    ...
}


class Question : NSManagedObject {

    @NSManaged var question: String
    @NSManaged var answer: String
    @NSManaged var options: String
    @NSManaged var optional: Bool

    @NSManaged var type: Music

    ...
}