如何保存自定义类型的核心数据与可编码协议斯威夫特

问题描述 投票:1回答:1

我想保存类型可编码的自定义对象,在这我能够存储的Int16类型。但对于[电影]输入Coredata其NSObject的,实体我有一个属性电影类型可转换的。

错误:没有“decodeIfPresent”候选人产生预期的语境结果类型“NSObject的?”

如何保存与可转换型这种自定义类型阵列

class MovieResults: Results, Codable {

        required convenience public init(from decoder: Decoder) throws  {
            guard let codingUserInfoKeyManagedObjectContext = CodingUserInfoKey.context,
                let managedObjectContext = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext,
                let entity = NSEntityDescription.entity(forEntityName: "Results", in: managedObjectContext) else {
                    fatalError("Failed to retrieve managed object context")
            }

            self.init(entity: entity, insertInto: managedObjectContext)

            let container = try decoder.container(keyedBy: CodingKeys.self)

            self.page = try container.decodeIfPresent(Int16.self, forKey: .page) ?? 0
            self.numberOfResults = try container.decodeIfPresent(Int16.self, forKey: .numberOfResults) ?? 0
            self.numberOfPages = try container.decodeIfPresent(Int16.self, forKey: .numberOfPages) ?? 0
            self.movies = try container.decodeIfPresent([Movie].self, forKey: .movies) ?? nil
        }

        // MARK: - Encodable
        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(page, forKey: .page)
            try container.encode(numberOfResults, forKey: .numberOfResults)
            try container.encode(numberOfPages, forKey: .numberOfPages)
            try container.encode(movies, forKey: .movies)
        }

        private enum CodingKeys: String, CodingKey {
            case page
            case numberOfResults = "total_results"
            case numberOfPages = "total_pages"
            case movies = "results"
        }
    }

电影阵列的类型是在CoreData可变形的自定义属性

class Movies: Movie, Codable {
    public func encode(to encoder: Encoder) throws {

    }

    required convenience init(from decoder: Decoder) throws {
        guard let codingUserInfoKeyManagedObjectContext = CodingUserInfoKey.context,
            let managedObjectContext = decoder.userInfo[codingUserInfoKeyManagedObjectContext] as? NSManagedObjectContext,
            let entity = NSEntityDescription.entity(forEntityName: "Movie", in: managedObjectContext) else {
                fatalError("Failed to decode User")
        }

        self.init(entity: entity, insertInto: managedObjectContext)

        let container = try decoder.container(keyedBy: CodingKeys.self)

        self.identifier = try container.decodeIfPresent(Int16.self, forKey: .identifier) ?? 0
        self.posterPath = try container.decodeIfPresent(String.self, forKey: .identifier)
        self.backdrop = try container.decodeIfPresent(String.self, forKey: .identifier)
        self.title = try container.decodeIfPresent(String.self, forKey: .identifier)
        self.releaseDate = try container.decodeIfPresent(String.self, forKey: .identifier)
        self.rating = try container.decodeIfPresent(Int16.self, forKey: .rating) ?? 0
        self.overview = try container.decodeIfPresent(String.self, forKey: .identifier)
    }

    enum CodingKeys: String, CodingKey {
        case identifier
        case posterPath = "poster_path"
        case backdrop = "backdrop_path"
        case title
        case releaseDate = "release_date"
        case rating = "vote_average"
        case overview
    }
}

有了这个,它的正常工作。

self.movies = try container.decodeIfPresent([Movies].self, forKey: .movies)! as NSObject

我继承NSManagedObject类这是正确的方式。我尝试使用扩展,但它抛出了初始化错误。?

public convenience init(from decoder: Decoder) throws

“初始化(来自:)”初始化程序要求只能由非final类的定义中的“必要”初始被满意“MovieResult”

swift core-data codable
1个回答
0
投票

我觉得这可能更简单的方式来完成。这里是你如何给一试。这里是MovieResult类[这是好事,有奇异的类的名称。

公共类MovieResult:可编码{公共变种stringVariable:字符串公共变种了IntVariable:诠释

public init(stringVariable: String, intVariable: Int) {
    self.stringVariable = stringVariable
    self.intVariable = intVariable
}

}

在这里,您可以在MovieResult坚持UserDefaults

public var savedMovieResult: MovieResult? {
    get {
        let data = UserDefaults.standard.object(forKey: "savedMovieResultKey") as? Data
        var movieResult: MovieResult?
        if let data = data {
            do {
                movieResult = try PropertyListDecoder().decode(MovieResult.self, from: data)
            } catch {
                print(error)
            }
        }
        return movieResult
    } set {
        do {
            try UserDefaults.standard.set(PropertyListEncoder().encode(newValue), forKey: "savedMovieResultKey")
            UserDefaults.standard.synchronize()
        } catch {
            print(error)
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.