【问题标题】:Save to CoreData array of strings with Codable使用 Codable 保存到 CoreData 字符串数组
【发布时间】:2019-12-12 09:42:49
【问题描述】:

我被困住了。 我有 json(电影数组)。我正在尝试使用 Codable 协议解析它,并保存到核心数据。 问题是 Movie 对象具有流派数组(字符串数组)。我创建了两个实体:电影和流派(具有一对多的关系)。解析电影对象没有问题,但是当我尝试解析流派时 - 它不起作用。

有什么想法吗?

附:是的,我知道流派数组没有键“名称”。

{
"title": "Dawn of the Planet of the Apes",
"image": "https://api.androidhive.info/json/movies/1.jpg",
"rating": 8.3,
"releaseYear": 2014,
"genre": ["Action", "Drama", "Sci-Fi"]
},
{
"title": "District 9",
"image": "https://api.androidhive.info/json/movies/2.jpg",
"rating": 8,
"releaseYear": 2009,
"genre": ["Action", "Sci-Fi", "Thriller"]
}

电影模型:

@objc(Movie)
class Movie: NSManagedObject, Decodable {

    @NSManaged var title: String?
    @NSManaged var image: String?
    @NSManaged var rating: Float
    @NSManaged var releaseYear: Int
    @NSManaged var genres: Set<Genre>?

    enum apiKey: String, CodingKey {
        case title
        case image
        case rating
        case releaseYear
        case genres = "genre"
    }

    @nonobjc public class func request() -> NSFetchRequest<Movie> {
        return NSFetchRequest<Movie>(entityName: "Movie")
    }

    // MARK: - Decodable

    public required convenience init(from decoder: Decoder) throws {

        guard let contextUserInfoKey = CodingUserInfoKey.context,
            let manageObjContext = decoder.userInfo[contextUserInfoKey] as? NSManagedObjectContext,
            let manageObjMovie = NSEntityDescription.entity(forEntityName: "Movie", in: manageObjContext) else {
            fatalError("Error to getting context")
        }

        self.init(entity: manageObjMovie, insertInto: manageObjContext)

        let container = try decoder.container(keyedBy: apiKey.self)
        self.title = try container.decodeIfPresent(String.self, forKey: .title)
        self.image = try container.decodeIfPresent(String.self, forKey: .image)
        self.rating = try container.decodeIfPresent(Float.self, forKey: .rating) ?? 0
        self.releaseYear = try container.decodeIfPresent(Int.self, forKey: .releaseYear) ?? 0

        self.genres = try container.decodeIfPresent(Set<Genre>.self, forKey: .genres) ?? []        
    }
}

// MARK: Generated accessors for geonames
extension Movie {

    @objc(addGenresObject:)
    @NSManaged func addToGenres(_ value: Genre)

    @objc(setKeyObject:)
    @NSManaged func setKeyObject(_ value: String)
}

类型模型:

@objc(Genre)
class Genre: NSManagedObject, Decodable {

    @NSManaged var name: String?

    enum apiKey: String, CodingKey {
        case name
    }

    @nonobjc public class func request() -> NSFetchRequest<Genre> {
        return NSFetchRequest<Genre>(entityName: "Genre")
    }

    // MARK: - Decodable

    public required convenience init(from decoder: Decoder) throws {

        guard let contextUserInfoKey = CodingUserInfoKey.context,
            let manageObjContext = decoder.userInfo[contextUserInfoKey] as? NSManagedObjectContext,
            let manageObjGenre = NSEntityDescription.entity(forEntityName: "Genre", in: manageObjContext) else {
            fatalError("Error to getting context")
        }

        self.init(entity: manageObjGenre, insertInto: manageObjContext)

        let container = try decoder.container(keyedBy: apiKey.self)
        self.name = try container.decodeIfPresent(String.self, forKey: .name)
    }
}

【问题讨论】:

  • “它不工作”这是什么意思?请澄清。

标签: swift core-data codable


【解决方案1】:

您需要在Genre 中与Movie 建立反向关系。添加这个

@NSManaged var movie: Movie?

并在模型文件中建立连接。

然后解码一个字符串数组,将其映射到 Genre 实例,并在 init 方法的末尾将 self 分配给该关系

let genreData = try container.decodeIfPresent([String].self, forKey: .genres) ?? []
let genreArray = genreData.map { name in
    let genre = Genre(context: manageObjContext)
    genre.name = name
    genre.movie = self
    return genre
}
self.genres = Set(genreArray)

考虑使用从GenreMovie 的一对多关系,否则您将拥有大量具有相同名称的Genre 实例。并考虑减少 Core Data 类中的可选项。似乎 JSON 源始终提供所有字段。可以去掉很多冗余代码。

【讨论】:

    猜你喜欢
    • 2020-01-02
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2018-12-08
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多