{"id":1168,"date":"2017-10-10T10:02:55","date_gmt":"2017-10-10T01:02:55","guid":{"rendered":"http:\/\/blue-bear.jp\/kb\/?p=1168"},"modified":"2017-10-10T10:06:19","modified_gmt":"2017-10-10T01:06:19","slug":"swift-coredata%e3%82%92%e4%bd%bf%e7%94%a8%e3%81%97%e3%81%a6%e3%82%bf%e3%82%b9%e3%82%af%e3%82%92%e8%bf%bd%e5%8a%a0%e3%83%bb%e5%89%8a%e9%99%a4","status":"publish","type":"post","link":"https:\/\/blue-bear.jp\/kb\/swift-coredata%e3%82%92%e4%bd%bf%e7%94%a8%e3%81%97%e3%81%a6%e3%82%bf%e3%82%b9%e3%82%af%e3%82%92%e8%bf%bd%e5%8a%a0%e3%83%bb%e5%89%8a%e9%99%a4\/","title":{"rendered":"[swift] CoreData\u3092\u4f7f\u7528\u3057\u3066\u30bf\u30b9\u30af\u3092\u8ffd\u52a0\u30fb\u524a\u9664"},"content":{"rendered":"<p>CoreData\u3092\u4f7f\u7528\u3057\u3066\u30bf\u30b9\u30af\u3092\u8ffd\u52a0\u30fb\u524a\u9664\u3059\u308b\u306b\u306f\u4ee5\u4e0b\u306e\u30b3\u30fc\u30c9<\/p>\n<p>Closure\u3092\u4f7f\u7528\u3057\u3066\u3001\u4fdd\u5b58\u3084\u524a\u9664\u304c\u5b8c\u5168\u306b\u7d42\u4e86\u3057\u3066\u304b\u3089\u30c7\u30fc\u30bf\u306e\u518d\u8aad\u8fbc\u53ca\u3073Reload Table\u3092\u5b9f\u884c\u3057\u3066\u3044\u308b<\/p>\n<p>xcode Project\u3092CoreData\u306a\u3057\u3067\u4f5c\u6210\u3057\u3066\u3057\u307e\u3063\u305f\u306e\u3067\u3001\u9014\u4e2d\u304b\u3089CoreData\u3092\u8ffd\u52a0\u3057\u3066\u3044\u308b\u3002<\/p>\n<h2>CoreData\u306e\u4f5c\u6210<\/h2>\n<h3>Data Model\u30d5\u30a1\u30a4\u30eb\u306e\u4f5c\u6210<\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-1169 size-medium\" src=\"http:\/\/blue-bear.jp\/kb\/wp-content\/uploads\/2017\/10\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2017-10-10-9.51.45-300x135.png\" alt=\"\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8 2017-10-10 9.51.45\" width=\"300\" height=\"135\" srcset=\"https:\/\/blue-bear.jp\/kb\/wp-content\/uploads\/2017\/10\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2017-10-10-9.51.45-300x135.png 300w, https:\/\/blue-bear.jp\/kb\/wp-content\/uploads\/2017\/10\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2017-10-10-9.51.45.png 734w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>New File \u3067\u65b0\u898f\u30d5\u30a1\u30a4\u30eb\u3092\u4f5c\u6210\uff08CoreData -&gt; Data Model\uff09<\/p>\n<p>Data Model\u306e\u30d5\u30a1\u30a4\u30eb\u540d\u306f\u300cHitList\u300d\u3068\u3057\u3066\u3044\u308b\u305f\u3081\u3001Project\u5185\u306b\u300cHitList.xcdatamodeld\u300d\u3068\u3044\u3046\u30d5\u30a1\u30a4\u30eb\u304c\u8ffd\u52a0\u3055\u308c\u308b<\/p>\n<p>&nbsp;<\/p>\n<h3>\u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u3068Attribute\u3092\u8ffd\u52a0<\/h3>\n<p>\u4eca\u56de\u306fPerson\u3068\u3044\u3046Entity\uff08SQL\u3067\u8a00\u3046DB\u30c6\u30fc\u30d6\u30eb\uff09\u3092\u4f5c\u6210\u3057\u3001\u305d\u306e\u4e2d\u306eAttribute\uff08SQL\u3067\u8a00\u3046\u30ab\u30e9\u30e0\uff09\u306bName\u3092\u8ffd\u52a0\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>Add Entity\u3067\u300cPerson\u300d\u3068\u3044\u3046\u540d\u524d\u3067\u8ffd\u52a0<\/p>\n<p>Add Attirbute\u3067\u300cName\u300d\u3092\u8ffd\u52a0<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-1170\" src=\"http:\/\/blue-bear.jp\/kb\/wp-content\/uploads\/2017\/10\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2017-10-10-9.53.26-300x195.png\" alt=\"\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8 2017-10-10 9.53.26\" width=\"300\" height=\"195\" srcset=\"https:\/\/blue-bear.jp\/kb\/wp-content\/uploads\/2017\/10\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2017-10-10-9.53.26-300x195.png 300w, https:\/\/blue-bear.jp\/kb\/wp-content\/uploads\/2017\/10\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2017-10-10-9.53.26-768x499.png 768w, https:\/\/blue-bear.jp\/kb\/wp-content\/uploads\/2017\/10\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2017-10-10-9.53.26-1024x666.png 1024w, https:\/\/blue-bear.jp\/kb\/wp-content\/uploads\/2017\/10\/\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8-2017-10-10-9.53.26.png 1240w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>&nbsp;<\/p>\n<h2>AppDelegate.swift<\/h2>\n<p>AppDelegate.swift\u306b\u4ee5\u4e0b\u306e\u30b3\u30fc\u30c9\u3092\u8ffd\u52a0<\/p>\n<p>\uff0aCoreData\u3092\u6700\u521d\u304b\u3089Project\u306b\u8ffd\u52a0\u3057\u305f\u6642\u306f\u3001\u81ea\u52d5\u3067\u30b3\u30fc\u30c9\u304c\u8ffd\u52a0\u3055\u308c\u3066\u3044\u308b\u3002<\/p>\n<p>NSPersistentContainer\u306b\u306f\u5148\u7a0b\u4f5c\u6210\u3057\u305fData Model\u306e\u30d5\u30a1\u30a4\u30eb\u540d\u3092\u8a18\u8ff0\u3057\u3066\u304a\u304f<\/p>\n<pre class=\"\">\/\/ MARK: - Core Data stack\r\n\r\n  lazy var persistentContainer: NSPersistentContainer = {\r\n    \/*\r\n     The persistent container for the application. This implementation\r\n     creates and returns a container, having loaded the store for the\r\n     application to it. This property is optional since there are legitimate\r\n     error conditions that could cause the creation of the store to fail.\r\n     *\/\r\n    let container = NSPersistentContainer(name: \"<span style=\"color: #ff0000;\">HitList<\/span>\")\r\n    container.loadPersistentStores(completionHandler: { (storeDescription, error) in\r\n      if let error = error as NSError? {\r\n        \/\/ Replace this implementation with code to handle the error appropriately.\r\n        \/\/ fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.\r\n\r\n        \/*\r\n         Typical reasons for an error here include:\r\n         * The parent directory does not exist, cannot be created, or disallows writing.\r\n         * The persistent store is not accessible, due to permissions or data protection when the device is locked.\r\n         * The device is out of space.\r\n         * The store could not be migrated to the current model version.\r\n         Check the error message to determine what the actual problem was.\r\n         *\/\r\n        fatalError(\"Unresolved error \\(error), \\(error.userInfo)\")\r\n      }\r\n    })\r\n    return container\r\n  }()\r\n\r\n  \/\/ MARK: - Core Data Saving support\r\n\r\n  func saveContext () {\r\n    let context = persistentContainer.viewContext\r\n    if context.hasChanges {\r\n      do {\r\n        try context.save()\r\n      } catch {\r\n        \/\/ Replace this implementation with code to handle the error appropriately.\r\n        \/\/ fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.\r\n        let nserror = error as NSError\r\n        fatalError(\"Unresolved error \\(nserror), \\(nserror.userInfo)\")\r\n      }\r\n    }\r\n  }  \r\n<\/pre>\n<h2>ViewController.swift<\/h2>\n<p>ViewController\u306bTableView\u3092\u5b9f\u88c5<\/p>\n<p>fetchPersonData\u3067CoreData\u304b\u3089NSManagedObject\u3092\u8aad\u307f\u8fbc\u3093\u3067\u914d\u5217people\u306b\u8981\u7d20\u3068\u3057\u3066\u8ffd\u52a0\u3057\u3066\u3044\u308b\u3002<\/p>\n<p>NSManagedObject\u306fDictionary\u578b\u306a\u306e\u3067\u4e0b\u8a18\u306e\u3088\u3046\u306bAttribute\u540d\u3067\u305d\u308c\u305e\u308c\u306e\u8981\u7d20\u3092\u53d6\u5f97\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3002<\/p>\n<p>cell.textLabel?.text = person.value(forKeyPath: &#8220;name&#8221;) as? String<\/p>\n<pre class=\"\">\r\nimport UIKit\r\nimport CoreData\r\n\r\nclass ViewController: UIViewController {\r\n\r\n  @IBOutlet weak var tableView: UITableView!\r\n  var people: [NSManagedObject] = []\r\n\r\n  override func viewDidLoad() {\r\n    super.viewDidLoad()\r\n\r\n    title = \"The List\"\r\n    tableView.register(UITableViewCell.self,\r\n                       forCellReuseIdentifier: \"Cell\")\r\n  }\r\n\r\n  override func viewWillAppear(_ animated: Bool) {\r\n    super.viewWillAppear(animated)\r\n    \r\n    fetchPersonData(){\r\n      self.tableView.reloadData()\r\n    }\r\n  }\r\n\r\n  @IBAction func addName(_ sender: UIBarButtonItem) {\r\n\r\n    let alert = UIAlertController(title: \"New Name\",\r\n                                  message: \"Add a new name\",\r\n                                  preferredStyle: .alert)\r\n\r\n    let saveAction = UIAlertAction(title: \"Save\", style: .default) { [unowned self] action in\r\n\r\n      guard let textField = alert.textFields?.first,\r\n        let nameToSave = textField.text else {\r\n          return\r\n      }\r\n\r\n      self.saveName(name: nameToSave){\r\n        self.fetchPersonData() {\r\n          self.tableView.reloadData()\r\n        }\r\n      }\r\n    }\r\n\r\n    let cancelAction = UIAlertAction(title: \"Cancel\",\r\n                                     style: .default)\r\n\r\n    alert.addTextField()\r\n\r\n    alert.addAction(saveAction)\r\n    alert.addAction(cancelAction)\r\n\r\n    present(alert, animated: true)\r\n  }\r\n\r\n  func save(name: String) {\r\n    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {\r\n      return\r\n    }\r\n\r\n    let managedContext = appDelegate.persistentContainer.viewContext\r\n\r\n    let entity = NSEntityDescription.entity(forEntityName: \"Person\",\r\n                                            in: managedContext)!\r\n\r\n    let person = NSManagedObject(entity: entity,\r\n                                 insertInto: managedContext)\r\n\r\n    person.setValue(name, forKeyPath: \"name\")\r\n\r\n    do {\r\n      try managedContext.save()\r\n      people.append(person)\r\n    } catch let error as NSError {\r\n      print(\"Could not save. \\(error), \\(error.userInfo)\")\r\n    }\r\n  }\r\n}\r\n\r\n\/\/ MARK: - UITableViewDataSource\r\nextension ViewController: UITableViewDataSource {\r\n\r\n  func tableView(_ tableView: UITableView,\r\n                 numberOfRowsInSection section: Int) -&gt; Int {\r\n    return people.count\r\n  }\r\n\r\n  func tableView(_ tableView: UITableView,\r\n                 cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {\r\n\r\n    let person = people[indexPath.row]\r\n    let cell = tableView.dequeueReusableCell(withIdentifier: \"Cell\",\r\n                                             for: indexPath)\r\n    cell.textLabel?.text = person.value(forKeyPath: \"name\") as? String\r\n    return cell\r\n  }\r\n  \r\n  \r\n  func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {\r\n    if editingStyle == .delete {\r\n      let person = people[indexPath.row]\r\n\r\n      deleteName(managedObject: person){\r\n        self.fetchPersonData(){\r\n          self.tableView.deleteRows(at: [indexPath], with: .fade)\r\n          self.tableView.reloadData()\r\n        }\r\n      }\r\n\r\n    }\r\n  }\r\n  \r\n}\r\n\r\n\r\n\/\/MARK: Controll CoreData\r\n\r\nextension ViewController {\r\n  func saveName(name: String, completion: (()-&gt;Void)?) {\r\n    \r\n    guard let appDelegate =\r\n      UIApplication.shared.delegate as? AppDelegate else {\r\n        return\r\n    }\r\n    \r\n    let managedContext =\r\n      appDelegate.persistentContainer.viewContext\r\n    \r\n    let entity =\r\n      NSEntityDescription.entity(forEntityName: \"Person\",\r\n                                 in: managedContext)!\r\n    \r\n    let person = NSManagedObject(entity: entity,\r\n                                 insertInto: managedContext)\r\n    \r\n    person.setValue(name, forKeyPath: \"name\")\r\n    \r\n    do {\r\n      try managedContext.save()\r\n      completion?()\r\n    } catch let error as NSError {\r\n      print(\"Could not save. \\(error), \\(error.userInfo)\")\r\n    }\r\n  }\r\n  \r\n  func fetchPersonData(completion: (()-&gt;Void)?) {\r\n    \r\n    guard let appDelegate =\r\n      UIApplication.shared.delegate as? AppDelegate else {\r\n        return\r\n    }\r\n    \r\n    let managedContext =\r\n      appDelegate.persistentContainer.viewContext\r\n    \r\n    let fetchRequest =\r\n      NSFetchRequest(entityName: \"Person\")\r\n    \r\n    do {\r\n      people = try managedContext.fetch(fetchRequest)\r\n      completion?()\r\n    } catch let error as NSError {\r\n      print(\"Could not fetch. \\(error), \\(error.userInfo)\")\r\n    }\r\n  }\r\n  \r\n  func updateName(managedObject: NSManagedObject, newName: String, completion: (()-&gt;Void)?) {\r\n    \r\n    guard let appDelegate =\r\n      UIApplication.shared.delegate as? AppDelegate else {\r\n        return\r\n    }\r\n    \r\n    let managedContext =\r\n      appDelegate.persistentContainer.viewContext\r\n    \r\n    do {\r\n      managedObject.setValue(newName, forKey: \"name\")\r\n      \r\n      try managedContext.save()\r\n      completion?()\r\n    } catch {\r\n      \r\n    }\r\n  }\r\n  func deleteName(managedObject: NSManagedObject, completion: (()-&gt;Void)?) {\r\n    \r\n    guard let appDelegate =\r\n      UIApplication.shared.delegate as? AppDelegate else {\r\n        return\r\n    }\r\n    \r\n    let managedContext =\r\n      appDelegate.persistentContainer.viewContext\r\n    \r\n    do {\r\n      managedContext.delete(managedObject)\r\n      print(\"deleteName\")\r\n      try managedContext.save()\r\n      completion?()\r\n    } catch {\r\n      print(\"deleteName error\")\r\n    }\r\n  }\r\n}\r\n\r\n\r\n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>CoreData\u3092\u4f7f\u7528\u3057\u3066\u30bf\u30b9\u30af\u3092\u8ffd\u52a0\u30fb<\/p>\n","protected":false},"author":1,"featured_media":88,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/blue-bear.jp\/kb\/wp-json\/wp\/v2\/posts\/1168"}],"collection":[{"href":"https:\/\/blue-bear.jp\/kb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blue-bear.jp\/kb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blue-bear.jp\/kb\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blue-bear.jp\/kb\/wp-json\/wp\/v2\/comments?post=1168"}],"version-history":[{"count":3,"href":"https:\/\/blue-bear.jp\/kb\/wp-json\/wp\/v2\/posts\/1168\/revisions"}],"predecessor-version":[{"id":1173,"href":"https:\/\/blue-bear.jp\/kb\/wp-json\/wp\/v2\/posts\/1168\/revisions\/1173"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blue-bear.jp\/kb\/wp-json\/wp\/v2\/media\/88"}],"wp:attachment":[{"href":"https:\/\/blue-bear.jp\/kb\/wp-json\/wp\/v2\/media?parent=1168"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blue-bear.jp\/kb\/wp-json\/wp\/v2\/categories?post=1168"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blue-bear.jp\/kb\/wp-json\/wp\/v2\/tags?post=1168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}