はじめに
core dataについて色々調べ、とりあえず実装できた状態です。
自分なりにまとめてみます。
tableviewcontrollerと、遷移先の項目を追加するview2つを作成します。
core data以外の操作は省略します🙇♂️
実装と解説
1 プロジェクト作成
まずはじめにプロジェクトを立ち上げる際に、User Core Dataを選択します。
すると、ファイル名.xcdatamodeldというファイルが追加されます、
2 tableviewcontrollerと追加用のviewcontrollerの実装
Core Dataの設定
①のファイルを選択すると、Core Dataの設定ができます。
②でEntityを追加します。
③が追加されます。Entityは今回データを入れておいて保管する場所になります。
今回はメモ内容の保存に使いますので、Memoという名前にしてみます。
Entityは大文字からの名前をつけるのが無難だそうです。
④の+を押すと、⑤のAttributeがが追加できます。これは今回追加するデータになります。
今回はメモの内容を保存するnameをstring型、チェックマークの状態を保存するcheckをBoolean型で設定します。
型はTypeから設定できます。
各項目のOptionalのチェックを外しておいてください。
ここで一旦ビルドしておきます。しておかないと後々エラーになるそうです。
コード
保存の処理
①viewContext
は変更などを見にいき、操作もできるメソッドで、それを定数contextに入れる
②そのcontextをMemo(context: context)に入れる事で、Core DataであるMemoの変更や操作ができるようになる。
③それを定数memoに入れたので、memo.attributeの項目を操作できる
④最後にsaveContext()でデータを保存して完了!
import UIKit
class AddViewController: UIViewController {
@IBOutlet weak var addTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func addButton(_ sender: Any) {
// persistentContainerは総監督の役割でcore dataに関連するNSManagedObjectContext・
// NS PesistentStoreCoordinator・NSpersistentStoreに指示を出せる。
// 以下のcontextはManagedObjectContextへの参照が含まれている。
// viewContextはNSManagedObjectContext型で、管理されているオブジェクトを操作したり、
// 変更を追跡したりする。
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
// (context:)はモデル内の単一のエンティティを表すNSManagedObject(この場合はMemo)のサブクラスに対してのみ、
// 合法的に呼び出すことができる。この場合、Memoの中で変更があるかとかをcontextで追跡し、
// それを呼び出して定数に入れているイメージかな?ManagedObjectのサブクラスを初期化し、
// 指定されたNSManagedObjectContextに挿入できるようになる。
let memo = Memo(context: context)
//memoはManagedObjectのサブクラスを初期化し、
//指定されたNSManagedObjectContextに挿入できるようになったので、
//以下のように値などを入れる事ができる。
memo.name = addTextField.text
memo.check = false
// 変更があれば保存する処理
(UIApplication.shared.delegate as! AppDelegate).saveContext()
navigationController!.popViewController(animated: true)
}
}
データを取得して、表示するコード
import UIKit
class MemoTableViewController: UITableViewController {
// 変数memosを用意して、core dataのMemo型を追加していくためにMemo型に指定する
var memos : [Memo] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: TableViewCell.reuseIdentifier)
}
override func viewWillAppear(_ animated: Bool) {
// データを取得する
getData()
tableView.reloadData()
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return memos.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: TableViewCell.reuseIdentifier, for: indexPath) as! TableViewCell
let memo = memos[indexPath.row]
cell.configure(isCheck: memo.check, name: memo.name!)
return cell
}
func getData() {
// 変更箇所を見にいく
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
do {
// あれば取得
memos = try context.fetch(Memo.fetchRequest())
}
catch {
print("読み込み失敗")
}
}
}
cellの内容
import UIKit
class TableViewCell: UITableViewCell {
@IBOutlet weak var label: UILabel!
@IBOutlet weak var checkImage: UIImageView!
static let image = UIImage(named: "check")
static let reuseIdentifier = "Cell1"
func configure(isCheck: Bool, name: String) {
// checkマークの表示の処理
checkImage.image = isCheck ? TableViewCell.image : nil
label.text = name
}
}
データの内容を削除
editingStyle内で処理を書きます。
また同じように、viewContextで操作できるようにします。
context.delete
で削除できます。
あとは削除した状態をsaveContext()
で保存してあげれはOKです。
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
if editingStyle == .delete {
let memo = memos[indexPath.row]
context.delete(memo)
(UIApplication.shared.delegate as! AppDelegate).saveContext()
do {
// あれば取得
memos = try context.fetch(Memo.fetchRequest())
}
catch {
print("読み込み失敗")
}
}
tableView.reloadData()
}
checkマークの切り替え
!を先頭につける事で値が反転できます。
これをdidSeleceRowAtに書く事で、cellのタップ時に切り替える事ができます。
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let memo = memos[indexPath.row]
memo.check = !memo.check
tableView.reloadData()
}
最後に
まだまだ理解できていないところがありますが、実装段階での理解の手助けになれば幸いです。
間違っている箇所などありましたら遠慮なくご指摘ください。