如何在核心数据中保存自定义对象列表?
How to save a custom list of objects in Core Data?
我是 Core Data 的新手,正在尝试保存由自定义对象组成的数组,但有一个小问题:我不知道如何以正确的方式做到这一点。应用程序从网络中检索数据并将其写入 Core Data 数据库。它包含几个数组和对象,它们是自定义对象。写字符串,整数等没有问题。但是如何保存自定义对象列表?用于从 Web 获取数据的对象与用于处理 Core Data 的对象有点不同,所以我不能只分配它们。当然,这可以在下一个循环中完成,但是没有更好的办法吗?
我是 Core Data 的新手,我正在寻找稍微复杂一些的操作的最佳解决方案。 Core Data 值得用于复杂操作吗?
核心数据服务:
protocol CoreDataServiceProtocol {
func saveCountries(countries: [Country])
func fetchCountries() -> [CountryCoreData]
}
final class CoreDataService : CoreDataServiceProtocol {
private var persistentContainer: NSPersistentContainer = {
let persistentContainer = NSPersistentContainer(name: "CountriesAPI")
persistentContainer.loadPersistentStores { _, error in
print(error?.localizedDescription ?? "")
}
return persistentContainer
}()
var viewContext: NSManagedObjectContext {
return persistentContainer.viewContext
}
func saveCountries(countries: [Country]) {
for country in countries {
let newCountry = CountryCoreData(context: viewContext)
for currency in country.currencies {
newCountry.addToCurrencyCoreData(currency)
}
//Below, I can easily create a new object that I want to assign as a parent property
var translation = TranslationCoreData(context: viewContext)
translation.br = country.translations?.br
newCountry.addToTranslationCoreData(translation)
//If there is no relationship between the models this way is pretty nice, but in my case there are several relationships
newCountry.setValue(country.alpha2Code, forKey: "alpha2Code")
newCountry.setValue(country.alpha3Code, forKey: "alpha3Code")
newCountry.setValue(country.altSpellings, forKey: "altSpellings")
newCountry.setValue(country.area, forKey: "area")
newCountry.setValue(country.borders, forKey: "borders")
newCountry.setValue(country.callingCodes, forKey: "callingCodes")
newCountry.setValue(country.capital, forKey: "capital")
newCountry.setValue(country.cioc, forKey: "cioc")
// newCountry.setValue(country.currencies, forKey: "currencies")
newCountry.setValue(country.demonym, forKey: "demonym")
newCountry.setValue(country.flag, forKey: "flag")
newCountry.setValue(country.gini, forKey: "gini")
//newCountry.setValue(country.id, forKey: "id")
// newCountry.setValue(country.languages, forKey: "languages")
newCountry.setValue(country.name, forKey: "name")
newCountry.setValue(country.nativeName, forKey: "nativeName")
newCountry.setValue(country.numericCode, forKey: "numericCode")
newCountry.setValue(country.population, forKey: "population")
newCountry.setValue(country.region, forKey: "region")
// newCountry.setValue(country.regionalBlocs, forKey: "regionalBlocs")
newCountry.setValue(country.subregion, forKey: "subregion")
newCountry.setValue(country.timezones, forKey: "timezones")
newCountry.setValue(country.topLevelDomain, forKey: "topLevelDomain")
// newCountry.setValue(country.translations, forKey: "translations")
}
do {
try viewContext.save()
print("Success")
} catch {
print("Error saving: \(error.localizedDescription)")
}
}
CoreDataxcdatamodel 生成的模型 - CountryCoreData:
import Foundation
import CoreData
extension CountryCoreData {
@nonobjc public class func fetchRequest() -> NSFetchRequest<CountryCoreData> {
return NSFetchRequest<CountryCoreData>(entityName: "CountryCoreData")
}
@NSManaged public var alpha2Code: String?
@NSManaged public var alpha3Code: String?
@NSManaged public var altSpellings: [String]?
@NSManaged public var area: Double
@NSManaged public var borders: [String]?
@NSManaged public var callingCodes: [String]?
@NSManaged public var capital: String?
@NSManaged public var cioc: String?
@NSManaged public var currencies: [CurrencyCoreData]?
@NSManaged public var demonym: String?
@NSManaged public var flag: String?
@NSManaged public var gini: Double
@NSManaged public var id: UUID?
@NSManaged public var languages: [LanguageCoreData]?
@NSManaged public var name: String?
@NSManaged public var nativeName: String?
@NSManaged public var numericCode: String?
@NSManaged public var population: Int16
@NSManaged public var region: String?
@NSManaged public var regionalBlocks: [RegionalBlockCoreData]?
@NSManaged public var subregion: String?
@NSManaged public var timezones: [String]?
@NSManaged public var topLevelDomain: [String]?
@NSManaged public var translations: [TranslationCoreData]?
@NSManaged public var currencyCoreData: NSSet?
@NSManaged public var languageCoreData: NSSet?
@NSManaged public var regionalBlockCoreData: NSSet?
@NSManaged public var translationCoreData: NSSet?
}
// MARK: Generated accessors for currencyCoreData
extension CountryCoreData {
@objc(addCurrencyCoreDataObject:)
@NSManaged public func addToCurrencyCoreData(_ value: CurrencyCoreData)
@objc(removeCurrencyCoreDataObject:)
@NSManaged public func removeFromCurrencyCoreData(_ value: CurrencyCoreData)
@objc(addCurrencyCoreData:)
@NSManaged public func addToCurrencyCoreData(_ values: NSSet)
@objc(removeCurrencyCoreData:)
@NSManaged public func removeFromCurrencyCoreData(_ values: NSSet)
}
// MARK: Generated accessors for languageCoreData
extension CountryCoreData {
@objc(addLanguageCoreDataObject:)
@NSManaged public func addToLanguageCoreData(_ value: LanguageCoreData)
@objc(removeLanguageCoreDataObject:)
@NSManaged public func removeFromLanguageCoreData(_ value: LanguageCoreData)
@objc(addLanguageCoreData:)
@NSManaged public func addToLanguageCoreData(_ values: NSSet)
@objc(removeLanguageCoreData:)
@NSManaged public func removeFromLanguageCoreData(_ values: NSSet)
}
// MARK: Generated accessors for regionalBlockCoreData
extension CountryCoreData {
@objc(addRegionalBlockCoreDataObject:)
@NSManaged public func addToRegionalBlockCoreData(_ value: RegionalBlockCoreData)
@objc(removeRegionalBlockCoreDataObject:)
@NSManaged public func removeFromRegionalBlockCoreData(_ value: RegionalBlockCoreData)
@objc(addRegionalBlockCoreData:)
@NSManaged public func addToRegionalBlockCoreData(_ values: NSSet)
@objc(removeRegionalBlockCoreData:)
@NSManaged public func removeFromRegionalBlockCoreData(_ values: NSSet)
}
// MARK: Generated accessors for translationCoreData
extension CountryCoreData {
@objc(addTranslationCoreDataObject:)
@NSManaged public func addToTranslationCoreData(_ value: TranslationCoreData)
@objc(removeTranslationCoreDataObject:)
@NSManaged public func removeFromTranslationCoreData(_ value: TranslationCoreData)
@objc(addTranslationCoreData:)
@NSManaged public func addToTranslationCoreData(_ values: NSSet)
@objc(removeTranslationCoreData:)
@NSManaged public func removeFromTranslationCoreData(_ values: NSSet)
}
extension CountryCoreData : Identifiable {
}
我觉得先改这些东西
而不是这个
newCountry.setValue(country.alpha2Code, forKey: "alpha2Code")
添加这一行
newCountry.alpha2Code = country.alpha2Code
在您的“保存国家/地区”功能中这样做
func saveCountries(countries: [Country]) {
for country in countries {
let newCountry = CountryCoreData(context: viewContext)
newCountry.alpha2Code = country.alpha2Code//add this line
}
saveContext()
}
创建 ViewContext 函数以便您可以重复使用它!
func saveContext(){
do {
try viewContext.save()
print("Success")
} catch {
print("Error saving: \(error.localizedDescription)")
}
}
使用 Transformable 类型,您可以直接在 CoreData 中保存数组,而无需 for 循环
我是 Core Data 的新手,正在尝试保存由自定义对象组成的数组,但有一个小问题:我不知道如何以正确的方式做到这一点。应用程序从网络中检索数据并将其写入 Core Data 数据库。它包含几个数组和对象,它们是自定义对象。写字符串,整数等没有问题。但是如何保存自定义对象列表?用于从 Web 获取数据的对象与用于处理 Core Data 的对象有点不同,所以我不能只分配它们。当然,这可以在下一个循环中完成,但是没有更好的办法吗? 我是 Core Data 的新手,我正在寻找稍微复杂一些的操作的最佳解决方案。 Core Data 值得用于复杂操作吗?
核心数据服务:
protocol CoreDataServiceProtocol {
func saveCountries(countries: [Country])
func fetchCountries() -> [CountryCoreData]
}
final class CoreDataService : CoreDataServiceProtocol {
private var persistentContainer: NSPersistentContainer = {
let persistentContainer = NSPersistentContainer(name: "CountriesAPI")
persistentContainer.loadPersistentStores { _, error in
print(error?.localizedDescription ?? "")
}
return persistentContainer
}()
var viewContext: NSManagedObjectContext {
return persistentContainer.viewContext
}
func saveCountries(countries: [Country]) {
for country in countries {
let newCountry = CountryCoreData(context: viewContext)
for currency in country.currencies {
newCountry.addToCurrencyCoreData(currency)
}
//Below, I can easily create a new object that I want to assign as a parent property
var translation = TranslationCoreData(context: viewContext)
translation.br = country.translations?.br
newCountry.addToTranslationCoreData(translation)
//If there is no relationship between the models this way is pretty nice, but in my case there are several relationships
newCountry.setValue(country.alpha2Code, forKey: "alpha2Code")
newCountry.setValue(country.alpha3Code, forKey: "alpha3Code")
newCountry.setValue(country.altSpellings, forKey: "altSpellings")
newCountry.setValue(country.area, forKey: "area")
newCountry.setValue(country.borders, forKey: "borders")
newCountry.setValue(country.callingCodes, forKey: "callingCodes")
newCountry.setValue(country.capital, forKey: "capital")
newCountry.setValue(country.cioc, forKey: "cioc")
// newCountry.setValue(country.currencies, forKey: "currencies")
newCountry.setValue(country.demonym, forKey: "demonym")
newCountry.setValue(country.flag, forKey: "flag")
newCountry.setValue(country.gini, forKey: "gini")
//newCountry.setValue(country.id, forKey: "id")
// newCountry.setValue(country.languages, forKey: "languages")
newCountry.setValue(country.name, forKey: "name")
newCountry.setValue(country.nativeName, forKey: "nativeName")
newCountry.setValue(country.numericCode, forKey: "numericCode")
newCountry.setValue(country.population, forKey: "population")
newCountry.setValue(country.region, forKey: "region")
// newCountry.setValue(country.regionalBlocs, forKey: "regionalBlocs")
newCountry.setValue(country.subregion, forKey: "subregion")
newCountry.setValue(country.timezones, forKey: "timezones")
newCountry.setValue(country.topLevelDomain, forKey: "topLevelDomain")
// newCountry.setValue(country.translations, forKey: "translations")
}
do {
try viewContext.save()
print("Success")
} catch {
print("Error saving: \(error.localizedDescription)")
}
}
CoreDataxcdatamodel 生成的模型 - CountryCoreData:
import Foundation
import CoreData
extension CountryCoreData {
@nonobjc public class func fetchRequest() -> NSFetchRequest<CountryCoreData> {
return NSFetchRequest<CountryCoreData>(entityName: "CountryCoreData")
}
@NSManaged public var alpha2Code: String?
@NSManaged public var alpha3Code: String?
@NSManaged public var altSpellings: [String]?
@NSManaged public var area: Double
@NSManaged public var borders: [String]?
@NSManaged public var callingCodes: [String]?
@NSManaged public var capital: String?
@NSManaged public var cioc: String?
@NSManaged public var currencies: [CurrencyCoreData]?
@NSManaged public var demonym: String?
@NSManaged public var flag: String?
@NSManaged public var gini: Double
@NSManaged public var id: UUID?
@NSManaged public var languages: [LanguageCoreData]?
@NSManaged public var name: String?
@NSManaged public var nativeName: String?
@NSManaged public var numericCode: String?
@NSManaged public var population: Int16
@NSManaged public var region: String?
@NSManaged public var regionalBlocks: [RegionalBlockCoreData]?
@NSManaged public var subregion: String?
@NSManaged public var timezones: [String]?
@NSManaged public var topLevelDomain: [String]?
@NSManaged public var translations: [TranslationCoreData]?
@NSManaged public var currencyCoreData: NSSet?
@NSManaged public var languageCoreData: NSSet?
@NSManaged public var regionalBlockCoreData: NSSet?
@NSManaged public var translationCoreData: NSSet?
}
// MARK: Generated accessors for currencyCoreData
extension CountryCoreData {
@objc(addCurrencyCoreDataObject:)
@NSManaged public func addToCurrencyCoreData(_ value: CurrencyCoreData)
@objc(removeCurrencyCoreDataObject:)
@NSManaged public func removeFromCurrencyCoreData(_ value: CurrencyCoreData)
@objc(addCurrencyCoreData:)
@NSManaged public func addToCurrencyCoreData(_ values: NSSet)
@objc(removeCurrencyCoreData:)
@NSManaged public func removeFromCurrencyCoreData(_ values: NSSet)
}
// MARK: Generated accessors for languageCoreData
extension CountryCoreData {
@objc(addLanguageCoreDataObject:)
@NSManaged public func addToLanguageCoreData(_ value: LanguageCoreData)
@objc(removeLanguageCoreDataObject:)
@NSManaged public func removeFromLanguageCoreData(_ value: LanguageCoreData)
@objc(addLanguageCoreData:)
@NSManaged public func addToLanguageCoreData(_ values: NSSet)
@objc(removeLanguageCoreData:)
@NSManaged public func removeFromLanguageCoreData(_ values: NSSet)
}
// MARK: Generated accessors for regionalBlockCoreData
extension CountryCoreData {
@objc(addRegionalBlockCoreDataObject:)
@NSManaged public func addToRegionalBlockCoreData(_ value: RegionalBlockCoreData)
@objc(removeRegionalBlockCoreDataObject:)
@NSManaged public func removeFromRegionalBlockCoreData(_ value: RegionalBlockCoreData)
@objc(addRegionalBlockCoreData:)
@NSManaged public func addToRegionalBlockCoreData(_ values: NSSet)
@objc(removeRegionalBlockCoreData:)
@NSManaged public func removeFromRegionalBlockCoreData(_ values: NSSet)
}
// MARK: Generated accessors for translationCoreData
extension CountryCoreData {
@objc(addTranslationCoreDataObject:)
@NSManaged public func addToTranslationCoreData(_ value: TranslationCoreData)
@objc(removeTranslationCoreDataObject:)
@NSManaged public func removeFromTranslationCoreData(_ value: TranslationCoreData)
@objc(addTranslationCoreData:)
@NSManaged public func addToTranslationCoreData(_ values: NSSet)
@objc(removeTranslationCoreData:)
@NSManaged public func removeFromTranslationCoreData(_ values: NSSet)
}
extension CountryCoreData : Identifiable {
}
我觉得先改这些东西
而不是这个
newCountry.setValue(country.alpha2Code, forKey: "alpha2Code")
添加这一行
newCountry.alpha2Code = country.alpha2Code
在您的“保存国家/地区”功能中这样做
func saveCountries(countries: [Country]) {
for country in countries {
let newCountry = CountryCoreData(context: viewContext)
newCountry.alpha2Code = country.alpha2Code//add this line
}
saveContext()
}
创建 ViewContext 函数以便您可以重复使用它!
func saveContext(){
do {
try viewContext.save()
print("Success")
} catch {
print("Error saving: \(error.localizedDescription)")
}
}
使用 Transformable 类型,您可以直接在 CoreData 中保存数组,而无需 for 循环