Swift

swift:超初心者向け!UserDefaultsでデータ保存する!


今回は、永続的にデータを保持することができる『UserDefaults』についてです。

 

『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を配置しましょう。

大きさもいい感じ調節してください。

tableView

 

 

次にUITableViewCellも配置しましょう。

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

cellOnTableView

identifierは『cell』にしてください。

cellって何??という方は、

前に書いたUITableViewの使い方についての記事をご参照ください。

swift3:初心者向け!UITableViewの使い方:delegate・datasourceについて

 

 

次に,

todoを入力するUITextFieldを配置してください。

大きさを整えて、

backgroundもおしゃれな色に変更しましょう。こっちの方が見やすいです。

textfieldOnTableView

 

 

 

さて、これで見た目は完璧です!

コードとの紐付けをします!

 

TableViewは『tableView』という名前で、

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-12-05-16-00-50 %e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-12-05-15-57-52

 

 

 

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

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-12-05-16-00-50

 

 

 

現在のコードはこのようになっていると思います。

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の中が空になったら完璧です!

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-12-05-19-16-41

 

 

 

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()

データを保存し、永続化するメソッド。

データを保存した際に登場する。

よく忘れてしますので注意が必要。

 

 

 

だいたいこんな感じです!

 


ABOUT ME
ささお
3年目iOSエンジニア。 スタートアップで働いておりやす。 プログラミングスクールとエンジニアのキャリアを考えたい。 作ったアプリ - https://apps.apple.com/us/app/loverprofile/id1463563845?l=ja&ls=1