【徒然DB】気ままにUIKit-CoreData編1〜基本中の基本〜
概要
このマガジンは四十を過ぎたおっさんが、
を参考にStoryboardでiOSアプリを完全に趣味で楽しんでいるだけな記事を気ままに上げてます。
今回
をハイ、レッツゴする🕺
ここから先は、
実際の現場では、RealmやSQLite、その他のデータベースでやるかな
と思うので、あくまでも
番外編
以前の記事で書いてるとおり、
気ままに、今年中に、残りの記事を消化できればいいな
くらいなモノなので、参考にしたければ参考にしてね程度で記事にしてく〜〜〜
多分、おそらく全部は、正常に動かないだろうなと予想してまする🕺
CoreData周りだから、
データベースはRealmとか他のフレームワーク使ってるからいいや
とか、
データ管理のアプリなんて作らないからいらない
って人にはあまり参考にならないかも〜〜〜〜
ちなみにオイラも、
2Dゲームなんて今のところ作らないから、SpriteKit周りはやらないしね💦
こういう連載マガジンは必要そうなところから動かして、自分で作ってみて、、、
て感じでやってくのもひとつの方法
大系的にどんな機能があるかに触れたいとか理解したいって人は、全部触れた方がいいかなって思うけどね👀
前準備
念の為、
バックアップ
をいつもどおりやってから本題へ💃
本題
Core Dataとは、
アプリで入力または編集したデータを外部ファイルに保存する機能
NSUserDefault:大量または複雑なデータを扱うのに適してない。
Core Data:大量または複雑なデータを扱うのに適したフレームワーク。
ってことみたいね👀
Core Dataを使ってみる
なんだけど、元々、組み込んでいってるプロジェクトは、最初の段階で
Use CoreDataにチェック
を入れて作り直しているので、既に
ポイント
CoreDataを後から追加すればいいで、Use CoreDataにチェックし忘れてる場合、
これまでの記事の機能を組み込んでいって、
最初からやり直すことが中々、労力になるので、
後から機能追加でCoreDataを使うことも想定して、最初からチェックを入れておいた方がいいんだよね〜〜〜
実際、クライアントの要求なんていつ変わるかわからないし。
ま、SwiftUIでやる分には、ビュー自体は全てコードで作るからそこまで手間ではないんだけどね💦
⒈事前準備
//
// ViewController.swift
//
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var testLabel: UILabel!
@IBOutlet weak var testTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
//デリゲート先に自分を設定する。
testTextField.delegate = self
}
//Returnキー押下時の呼び出しメソッド
func textFieldShouldReturn(textField:UITextField) -> Bool {
//ラベルの値にテキストフィールドの値を追記する。
testLabel.text = testLabel.text! + "," + testTextField.text!
//キーボードをしまう
self.view.endEditing(true)
return true
}
}
を参考に〜〜〜
class CoreDataStandardViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var myLabel: UILabel!
@IBOutlet weak var myTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
//デリゲート先に自分を設定する。
myTextField.delegate = self
}
//Returnキー押下時の呼び出しメソッド
func textFieldShouldReturn(_ textField:UITextField) -> Bool {
//ラベルの値にテキストフィールドの値を追記する。
myLabel.text = myLabel.text! + "," + myTextField.text!
//キーボードをしまう
self.view.endEditing(true)
return true
}
}
⒉ここからの操作を間違うと面倒臭そうなので、一旦バックアップ
こういうデカすぎるプロジェクトファイルでは未知の領域なんだけど、正常にできるか試す意味でもやってく〜〜〜🕺
⒊モデルにエンティティを追加
エンティティとは、
オブジェクトが持つプロパティや関係が記載されている定義書
👉管理オブジェクトコンテキストに格納するオブジェクト1つにつき1つのエンティティが割り当たる。
てことらしい👀
っと、大きくしとこう
⒋コード組み込み
//
// ViewController.swift
//
import UIKit
import CoreData
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var testLabel: UILabel!
@IBOutlet weak var testTextField: UITextField!
//管理オブジェクトコンテキスト
var managedContext:NSManagedObjectContext!
//最初からあるメソッド
override func viewDidLoad() {
super.viewDidLoad()
do {
//管理オブジェクトコンテキストを取得する。
let applicationDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
managedContext = applicationDelegate.managedObjectContext
//管理オブジェクトコンテキストからPlayerエンティティを取得する。
let fetchRequest = NSFetchRequest(entityName: "Player")
let result = try managedContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]
//すべてのPlayerエンティティの名前をラベルに表示する。
for data in result {
testLabel.text = testLabel.text! + "," + String(data.valueForKey("name")!)
}
//デリゲート先に自分を設定する。
testTextField.delegate = self
} catch {
print(error)
}
}
//Returnキー押下時の呼び出しメソッド
func textFieldShouldReturn(textField:UITextField) -> Bool {
do {
//ラベルの値にテキストフィールドの値を追記する。
testLabel.text = testLabel.text! + "," + testTextField.text!
//新しいPlayerエンティティを管理オブジェクトコンテキストに格納する。
let player = NSEntityDescription.insertNewObjectForEntityForName("Player", inManagedObjectContext: managedContext)
//Playerエンティティの名前にテキストフィールドの値を設定する。
player.setValue(testTextField.text, forKey:"name")
//管理オブジェクトコンテキストの中身を永続化する。
try managedContext.save()
//キーボードをしまう
self.view.endEditing(true)
} catch {
print(error)
}
return true
}
}
を参考に〜〜〜
どうやら既に書き方が大分、異なっている様子💦
なので、2時間くらいかかったけど、以下に書き換え〜〜〜〜
今回のコード(まとめ)
class CoreDataStandardViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var myLabel: UILabel!
@IBOutlet weak var myTextField: UITextField!
//管理オブジェクトコンテキスト
var managedContext:NSManagedObjectContext!
//最初からあるメソッド
override func viewDidLoad() {
super.viewDidLoad()
do {
//管理オブジェクトコンテキストを取得する。
let applicationDelegate = UIApplication.shared.delegate as! AppDelegate
managedContext = applicationDelegate.persistentContainer.viewContext
//管理オブジェクトコンテキストからPlayerエンティティを取得する。
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Player")
let result = try managedContext.fetch(fetchRequest) as! [NSManagedObject]
//すべてのPlayerエンティティの名前をラベルに表示する。
for data in result {
myLabel.text = myLabel.text! + "," + String(describing: data.value(forKey:"name")!)
}
//デリゲート先に自分を設定する。
myTextField.delegate = self
} catch {
print(error)
}
}
//Returnキー押下時の呼び出しメソッド
func textFieldShouldReturn(_ textField:UITextField) -> Bool {
do {
//ラベルの値にテキストフィールドの値を追記する。
myLabel.text = myLabel.text! + "," + myTextField.text!
//新しいPlayerエンティティを管理オブジェクトコンテキストに格納する。
let player = NSEntityDescription.insertNewObject(forEntityName: "Player", into: managedContext)
//Playerエンティティの名前にテキストフィールドの値を設定する。
player.setValue(myTextField.text, forKey:"name")
//管理オブジェクトコンテキストの中身を永続化する。
try managedContext.save()
//キーボードをしまう
self.view.endEditing(true)
} catch {
print(error)
}
return true
}
}
⒌シミュレータで実行
ブラッシュアップ
AutoLayout
地球儀ボタン追加
記事公開後、
なんだが、実機だとちょっとテキストフィールドの高さがあまりにも狭いので〜〜〜
今回の教訓
当時と比べて、仕様が大幅に変更になってるので、触れたことがない人には、おそらく、今回のサイト記事を見ただけで、中々難しいのでは?👀
って感じ。
現在の仕様は、
なんかを参考にすればいいかなって感じ💦
個人的に詰まったのは、
//すべてのPlayerエンティティの名前をラベルに表示する。
for data in result {
testLabel.text = testLabel.text! + "," + String(data.valueForKey("name")!)
}
↓
//すべてのPlayerエンティティの名前をラベルに表示する。
for data in result {
myLabel.text = myLabel.text! + "," + String(describing: data.value(forKey:"name")!)
}
に書き振りが変わってたので、ああでもないこうでもないと悩んだくらい💦
結構、難しいこととか高機能な単体ビューなんかのサイト記事は調べれば山ほどあるんだけど、意外と、
String(data.valueForKey("name")!)
↓
String(describing: data.value(forKey:"name")!)
に変わったみたいな、知ってる人には当たり前のことの方がネットには載っていなかったりするからね〜〜〜〜🤔
知ってて当たり前、自己解決出来て当たり前
で、素通りされちゃうからね👀
独学の人が詰まるのって
本では、簡単すぎる内容か、いきなり小難しいことばかり詳しく書き過ぎている
キーワード検索しても、自分が本当に知りたい肝心なところが中々載っていない
Swiftの文法と実際のアプリがどう繋がってるかがわかる書き方になっていない
のいずれかで結果、
もういいやって感じになるんじゃないかな〜〜〜
*ま、オイラは所詮、
完全に趣味だから、
心ゆくまま気ままになんであんまり関係ないんだけどね💦
Apple公式
さて、次回は
をレッツゴする🕺
多分、どこかで完全にできないってところが出てきそうな予感大なんだけど、できるところまでは進められたらいいなあ🤔
ここからは、前々回までみたいにハイペースでやらずに、じっくりゆっくりやる〜!
焦る必要もないしねー!
何より、
CoreData(とCloudKit)は、Appleが純正で出してるモバイルデータベース用のフレームワーク
👉連携なんざ意識しなくていいから、何かあった時に調べるコストが減る
キーとバリュー(キーと値)だけで管理していく
👉DB(データベース)の基本をやるのにちょうど良い
これで
これだけビューを組み込んでるデカいプロジェクトでも、
💃普通にCoreDataが動く🕺
てことは証明できたね