简体   繁体   中英

How to store a dictionary of arrays of custom objects using NSCoding swift

So I'm having a problem. I'm making this app that currently stores information for "Courses". However, I've been changing the app a lot, and now I want a dictionary of courses. I need to be able to save this dictionary of courses and load it from any class.

Currently in Course.swift I have the NSCoding setup. My program writes and reads all course information. But now I want to change it so that it writes this dictionary instead of all the courses. I don't have another data class that holds this dictionary, it's just being held in my "StartUpViewController.swift".

class Course: NSObject, NSCoding {

// MARK: Properties
var courseName : String
var projects : [String]
var projectMarks : [Double]
var projectOutOf : [Double]
var projectWeights : [Double]

// MARK: Archiving Paths

static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("courses")
// MARK: Types

struct PropertyKey {
    static let courseNameKey = "courseName"
    static let projectsKey = "projects"
    static let projectMarksKey = "projectMarks"
    static let projectOutOfKey = "projectOutOf"
    static let projectWeightsKey = "projectWeights"
}

// MARK: NSCoding

func encode(with aCoder: NSCoder) {
    aCoder.encode(courseName, forKey: PropertyKey.courseNameKey)
    aCoder.encode(projects, forKey: PropertyKey.projectsKey)
    aCoder.encode(projectMarks, forKey: PropertyKey.projectMarksKey)
    aCoder.encode(projectOutOf, forKey: PropertyKey.projectOutOfKey)
    aCoder.encode(projectWeights, forKey: PropertyKey.projectWeightsKey)
}

required convenience init?(coder aDecoder: NSCoder) {
    let courseName = aDecoder.decodeObject(forKey: PropertyKey.courseNameKey) as! String
    let projects = aDecoder.decodeObject(forKey: PropertyKey.projectsKey) as! [String]
    let projectMarks = aDecoder.decodeObject(forKey: PropertyKey.projectMarksKey) as! [Double]
    let projectOutOf = aDecoder.decodeObject(forKey: PropertyKey.projectOutOfKey) as! [Double]
    let projectWeights = aDecoder.decodeObject(forKey: PropertyKey.projectWeightsKey) as! [Double]

    self.init(courseName: courseName, projects: projects, projectMarks: projectMarks, projectOutOf: projectOutOf, projectWeights: projectWeights)
}

How do I go about doing this? Do I keep the Course.swift using NSCoding, or do I have to only put NSCoding in my View Controller?

class StartUpViewController: UIViewController {

var groups: [String: [Course]?] = [:]

...
}

Create a new class conforming to NSCoding.

This new class has a property :

var courses: [String : Course]?

And the methods :

func encode(with aCoder: NSCoder) {
    if let courses = courses {
        aCoder.encode(courses, forKey: "courses")
    }
}

required convenience init?(coder aDecoder: NSCoder) { 
    courses = aDecoder.decodeObject(forKey: "courses") as? [String : Course]
    }

And leave your NSCoding protocol implementation in Course class because it will be used when encoding the dictionary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM