iOS - 数据在 Core Data 中保存一次

标签 ios swift core-data

我正在尝试将一堆数据保存到核心数据中。我可以设法将所有数据保存到核心数据中,但是在核心数据中包含重复数据是没有意义的,因为该函数将在项目的每个构建中执行一次。我现在考虑的方法是在向实体添加新记录之前清空实体的记录。只是想知道是否有另一种方法来确保数据只保留一次?

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/

相关文章:

ios - 属性映射未正确关联。为什么?

iphone - 在类之间传递NSString

ios - Google SignIn SFSafariViewController/WebView 在接受权限后重定向到 Google.com

ios - 添加从 iPhone 网页在应用程序商店中打开的链接

ios - Xcode6 ImageView + Assets 目录。图片未显示

swift - 重载方法,唯一的区别是可选类型与非可选类型

ios - 在 Swift 中将 UIPageViewController 的逻辑实现为 UIViewController 的 subview

ios - 完善我的 MagicalRecord 导入

ios - 我必须保存()我的 NSManagedObjectContext 吗?

objective-c - 类名上的 @objc 注释与类本身