今回は、永続的にデータを保持することができる『UserDefaults』についてです。
Contents
『UserDefaults』って何??
UserDefaultsとは、iosアプリ内にデータを保存する方法の一つです。
iPhone内の容量を使用するので、あまりたくさんのデータは保存しません。
シンプルなメモ帳アプリなどに使われるものです。
前にご紹介した『Realm』に近いですね。ご参考までに。
swift3:超簡単データベース!Realmを使った超簡単お手軽Todoアプリ!!
データの取り扱い方に関してはweb上に落とす方法がありますね。
それは『Firebase』『NiftyCloud』などなどMbaasと呼ばれる種類のものです。
前にFirebaseをご紹介しました。
swift3:超簡単!リアルタイムチャットができるFirebaseを試してみた。(超簡単編)
それらを利用すれば、iPhoneの容量を使わずにできます。
SNSアプリなどの他人とやりとりをしたりするアプリはweb上にデータベースを持っています。
じゃあweb上にデータベースを持てば、UserDefaultsいらなくない!?
必要です!
そんな単純なものではないのです。
実は多くのアプリがiPhoneアプリ内にデータを持つUserDefaultsや
web上にデータを持つことの両方をしているのです。
みんな大好きLINEのアプリを想像してください。
テキストや画像がiPhone内に保存されているのがわかると思います。
あれがUserDefaultsを使用しているのかわかりませんが、
どんなアプリでもiPhone内にデータを保存することが多いことがわかると思います。
さて、UserDefaultsの必要性を説明したところで、初めて行きます。
今回は超絶簡単なTodoアプリもどきを作って行きます。
まずは新しいプロジェクトを立ち上げましょう!
プロジェクト名は『TestTodoApp』にしましょう。
作成完了したら、Main.storyboardを開きましょう。
そして、デフォルトで置いてあるUIViewControllerにUITableViewを配置しましょう。
大きさもいい感じ調節してください。

次にUITableViewCellも配置しましょう。
配置ができるとこのようにUITableViewの見た目がやや変化します。

identifierは『cell』にしてください。
cellって何??という方は、
前に書いたUITableViewの使い方についての記事をご参照ください。
swift3:初心者向け!UITableViewの使い方:delegate・datasourceについて
次に,
todoを入力するUITextFieldを配置してください。
大きさを整えて、
backgroundもおしゃれな色に変更しましょう。こっちの方が見やすいです。

さて、これで見た目は完璧です!
コードとの紐付けをします!
TableViewは『tableView』という名前で、


TextFieldは『textField』という名前にします。

現在のコードはこのようになっていると思います。
import UIKit class ViewController: UIViewController{ @IBOutlet weak var tableView: UITableView! @IBOutlet weak var textField: UITextField! override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } }
今回はreturnキーを押した時に、
UITextFieldに入力した文字列がUITableViewに反映されるようにしたいので、
このように編集します。
import UIKit class ViewController: UIViewController, UITextFieldDelegate, UITableViewDataSource{ @IBOutlet weak var tableView: UITableView! @IBOutlet weak var textField: UITextField! override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self textField.delegate = self } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // セルの数 return 10 } func numberOfSections(in tableView: UITableView) -> Int {// セクションの数 return 1 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {// セルの内容を決める。 let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) return cell } func textFieldShouldReturn(_ textField: UITextField) -> Bool {// returnキーを押した時の処理 self.textField.text = "" return true } }
UITextFieldDelegate
これは、returnキーを押した時の処理がデリゲートメソッドのため必要。
textFieldShouldReturn
func textFieldShouldReturn(_ textField: UITextField) -> Bool {// returnキーを押した時の処理 self.textField.text = "" // textFIeldが空になる。 return true }
UITableViewDatasource
これは、TableViewの内容を決めるために必要です。
TableViewの内容とは、
- セクションの数
- セルの数
- セルの内容 etc
です。
numberOfSections
これはセクションの数を決めることができるメソッドです。
戻り値に数字を指定します。今回は1にしました。
func numberOfSections(in tableView: UITableView) -> Int {// セクションの数 return 1 }
numberOfRowsInSection
これはセルの数を決めることができるメソッドです。
これも戻り値に数字を指定します。今はとりあえず10にしました。あとで変更します。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // セルの数 return 10 }
cellForRowAt
ここはかなり難しいところです。
まだ何もしていませんが、ここでセルの内容を決めます。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {// セルの内容を決める。 let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) return cell }
ではここでRUN!
実行して見ましょう。
まっさらさらな画面に色のついたtextFieldがあれば成功です!
こんな感じです。
textFieldに入力して、returnを押したらtextFieldの中が空になったら完璧です!

UserDefaults
ようやく、Userfaultsについてついてです。
ここで入力されたデータがtableViewに反映されるまでの流れを確認します。
配列todosを用意(まだ空)
↓
textFieldに入力
↓
textFieldに入力したデータを配列todosに格納
↓
配列todosをUserDefaultsに保存
↓
UserDefaultsから配列todosを取り出す。
↓
取り出した配列todosを配列todosに上書き。
↓
tableViewのセル番号と配列todosの番号があっているものが表示されるようにする。
ざっくりいうとこんな感じです。
import UIKit class ViewController: UIViewController, UITextFieldDelegate, UITableViewDataSource{ @IBOutlet weak var tableView: UITableView! @IBOutlet weak var textField: UITextField! var todos: Array<String> = [] let userDefaults = UserDefaults.standard override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self textField.delegate = self if let aaa = userDefaults.object(forKey: "todos") { todos = aaa as! Array<String> } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // セルの数 return todos.count } func numberOfSections(in tableView: UITableView) -> Int {// セクションの数 return 1 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {// セルの内容を決める。 let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) let todo = todos[indexPath.row] cell.textLabel?.text = todo return cell } func textFieldShouldReturn(_ textField: UITextField) -> Bool {// returnキーを押した時の処理 if let text = self.textField.text { todos.append(text) userDefaults.set(todos, forKey: "todos") userDefaults.synchronize() todos = userDefaults.object(forKey: "todos") as! Array<String> } self.textField.text = "" self.tableView.reloadData() //データをリロードする return true } }
UserDefaults.standard
UserDefaultsを参照している。
データを保存する時や
データを取り出す時などなど
様々な場面で登場する。
userDefaults.set(todos, forKey: “todos”)
データをセットするメソッド。
第一引数に保存したいデータを入れて、
第二引数に取り出す時に必要な合言葉を設定。
userDefaults.object(forKey: “todos”)
データを取り出すメソッド。
引数にsetメソッドで設定した合言葉を設定して、データを取り出す。
userDefaults.synchronize()
データを保存し、永続化するメソッド。
データを保存した際に登場する。
よく忘れてしますので注意が必要。
だいたいこんな感じです!