我正在尝试将一堆数据保存到核心数据中。我可以设法将所有数据保存到核心数据中,但是在核心数据中包含重复数据是没有意义的,因为该函数将在项目的每个构建中执行一次。我现在考虑的方法是在向实体添加新记录之前清空实体的记录。只是想知道是否有另一种方法来确保数据只保留一次?
func persistCurrencyData() {
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let currencyEntity = NSEntityDescription.entityForName("Currency", inManagedObjectContext: managedContext)
let countryEntity = NSEntityDescription.entityForName("Country", inManagedObjectContext: managedContext)
for currency in currencies {
let currencyObject = CurrencyCore(entity: currencyEntity!, insertIntoManagedObjectContext: managedContext)
currencyObject.setValue(currency.code, forKeyPath: "code")
currencyObject.setValue(currency.name, forKeyPath: "name")
for country in currency.country! {
let countryObject = CountryCore(entity: countryEntity!, insertIntoManagedObjectContext: managedContext)
countryObject.setValue(country.name, forKeyPath: "name")
countryObject.setValue(country.code, forKeyPath: "code")
countryObject.setValue(country.continent, forKeyPath: "continent")
countryObject.setValue(country.continentCode, forKeyPath: "continentCode")
countryObject.currency = currencyObject
}
}
do {
try managedContext.save()
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
}
更新:
感谢@Wain 给我这个主意。基本上,我为解决核心数据中重复数据的保存所做的工作是在我的 JSON 文件中包含一个 GUID。每次代码读取JSON文件时,都会将GUID保存到NSUserDefault
中,并将数据保存到core data中。当下次构建要再次读取 JSON 文件时,它会检查 GUID 是否与之前保存的 GUID 相同。如果不同,代码将读取 JSON 文件并重复上述过程。如果不是,它将继续并忽略它。
func requestCurrenciesData() {
getCurrenciesDataFromFileWithSuccess { (data) -> Void in
var json: [String: AnyObject]
do {
json = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions()) as! [String: AnyObject]
guard let currencyData = CurrencyData(json: json) else {
print("Error initializing object")
return
}
self.currencies = currencyData.currency!
// Checking the JSON's id is same as previous read
let defaults = NSUserDefaults.standardUserDefaults()
if let id = defaults.stringForKey("id")
{
if id == currencyData.id {
let notification = NSNotification(name: "CurrenciesDataUpdate", object: nil)
NSNotificationCenter.defaultCenter().postNotification(notification)
return
}
}
self.persistCurrencyDataForId(currencyData.id)
let notification = NSNotification(name: "CurrenciesDataUpdate", object: nil)
NSNotificationCenter.defaultCenter().postNotification(notification)
} catch {
print(error)
return
}
}
}
func persistCurrencyDataForId(id: String) {
// Save the new JSON's id into NSUserDefaults
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(id, forKey: "id")
// Delete all the records in existing table
deleteRecordsFromEntity("Country")
deleteRecordsFromEntity("Currency")
// Insert the new records
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let currencyEntity = NSEntityDescription.entityForName("Currency", inManagedObjectContext: managedContext)
let countryEntity = NSEntityDescription.entityForName("Country", inManagedObjectContext: managedContext)
for currency in currencies {
let currencyObject = CurrencyCore(entity: currencyEntity!, insertIntoManagedObjectContext: managedContext)
currencyObject.setValue(currency.code, forKeyPath: "code")
currencyObject.setValue(currency.name, forKeyPath: "name")
for country in currency.country! {
let countryObject = CountryCore(entity: countryEntity!, insertIntoManagedObjectContext: managedContext)
countryObject.setValue(country.name, forKeyPath: "name")
countryObject.setValue(country.code, forKeyPath: "code")
countryObject.setValue(country.continent, forKeyPath: "continent")
countryObject.setValue(country.continentCode, forKeyPath: "continentCode")
countryObject.currency = currencyObject
}
}
do {
try managedContext.save()
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
}
func deleteRecordsFromEntity(entityName: String) {
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let coordinator = appDelegate.persistentStoreCoordinator
let fetchRequest = NSFetchRequest(entityName: entityName)
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
do {
try coordinator.executeRequest(deleteRequest, withContext: managedContext)
} catch let error as NSError {
print(error)
}
}
最佳答案
一般来说,您可以说“如果我在数据存储中有任何货币条目,请不要添加更多”。这可以通过在第一次导入时添加一个标志以使用默认值或类似的东西来完成,但更好的选择是检查数据存储以查看它是否有任何货币条目。为此,请为 currencyEntity
创建一个提取请求并使用 countForFetchRequest:error:
,然后再继续使用 for currency in currencys {
。如果计数大于零,那么您应该返回而不是处理循环。
为了提高效率,实际上应该在下载和处理 JSON 之前进行此检查...
关于iOS - 数据在 Core Data 中保存一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35495522/