我试图保存可编码类型的自定义对象,我可以在其中存储Int16类型。但是对于Coredata中其[NSObject]实体的[Movie]类型,我有一个属性movie属于Transformable类型。
错误:没有'decodeIfPresent'候选者产生预期的上下文 结果类型为“ NSObject?”
如何使用可转换类型保存此自定义类型数组
[House[type = big, attributes =
{
House.KeyValue[key = door, value = HouseKind[value = black]],
House.KeyValue[key = window, value = HouseKind[value = white]]
},
garden = true,
flowers = {
House.KeyValue[key = rose, value = HouseKind[value = red]]
}
],
House[type = small, attributes =
{
House.KeyValue[key = door, value = HouseKind[value = red]],
House.KeyValue[key = swimmingpool, value = HouseKind[value = true]]
}
]},
flowers = {
House.KeyValue[key = rose, value = HouseKind[value = purple]]}
]
]
电影数组是CoreData中可转换类型的自定义属性
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"
}
}
有了它,就可以了。
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
}
}
我正在继承NSManagedObject类这是正确的方法吗?我试过了 使用扩展名,但会为初始化程序引发错误。?
self.movies = try container.decodeIfPresent([Movies].self, forKey: .movies)! as NSObject
初始化器要求'init(from :)'只能由 非最终类定义中的“必需”初始化程序 “ MovieResult”
答案 0 :(得分:0)
我认为这可以通过更简单的方式来完成。这是您可以尝试的方法。这是MovieResult
类[最好以单个名称表示类的名称。
公共类MovieResult:可编码{ public var string变量:字符串 public var intVariable:Int
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)
}
}
}