1日空いてしまった。。毎日更新しなければ。
今回はメモ帳アプリその2。前回作成したメモ帳アプリではアプリを落とすとデータがリセットされるのでデータを保存する必要がある。世間ではRealmというやつが流行っているらしいが初心者にはわからん。こちらのブログを参照しながら「NSUserDefaults」について学ぶ。
宣言するっぽい
どうやらNSUserDefaultsを使うときにはletで定義してあげるのが一般的な使い方っぽい。「NSUsesrDefaultsというデータを記録、呼び出しします〜」という宣言だとか。初心者には手順書がなくてコードだけ書かれていてもわからんのでとにかくパク、真似する。
let saves = NSUserDefaults.standardUserDefaults()
これだとエラーが表示される。どうやらSwiftのバージョンアップにより変わったらしい。
let saves = UserDefaults.standard
また、保存するときには「SetObject」で呼び出す時のキーワードを指定する。
呼び出すときには「StringForKey」でそのキーワードを使う。
「保存」ボタンが押されたら保存する
@IBAction func saveItem(_ sender: Any) { if (input.text != "") { saves.set(input.text, forKey: "myText") list.append(input.text!) input.text = "" self.navigationController?.popViewController(animated: true) } }
こちらも最初.setObjectを使っていたがrenameしてくれと言われた。
保存されたメモを取り出す
let saves = UserDefaults.standard list.text = saves.stringForKey("myText")
ということでこう書いたんだけれどもここで、Value of type ‘[String]’ has no member ‘text’と表示される。
先生に聞きました
まず色々まずいところがあって、letの宣言をグローバルには置いてはだめそうな。ちゃんと使うclassの中に書きましょうということ。(少し端折ってますが
import UIKit class TableViewController: UITableViewController, UISearchBarDelegate{ //元々の配列 var list = ["Buy milk", "Run 5 miles", "Get Peter", "Plant my new plants"]
userdefaultに入いれて一覧に戻ってきた時に呼び出すのでViewDidAppearに記述する。ただしここはライフサイクル的にあんまりよくないらしい。
override func viewDidAppear(_ animated: Bool) { //これやると重たくなるらしい ここで呼ぶのはよくない if let text = saves.object(forKey: "myText") as? String { list.append(text) myTableView.reloadData() } }
optionを押しながら定数textをクリックすると今textがどの型なのかがわかる。as? Stringはストリングなのかな?as! StringだったらこれはString(強制)。この辺難しい。
if let text = というのはもしtextが右辺だったら〜する。つまりここではtextにKey”myText”で保存されたデータがあったら、ということになる。
.synchronize()で保存までにかかるラグを無くす?
@IBAction func saveItem(_ sender: Any) { if (input.text != "") { saves.set(input.text, forKey: "myText") //保存する saves.synchronize() //すぐに保存する input.text = "" self.navigationController?.popViewController(animated: true) } }
入れとかないといけないらしい。
また、今だと同じkeyを持ってしまっているのでそれぞれ固有のkeyにしてあげる必要がある。uidを使うとユニークなものを持たせられるらしい。
難しいな−。