【swift】Realmを試してみる

今回はうまい(使いやすい)、安い(無料)、早い(高速)でデータベースが利用できる「Realm」を使ってToDoリストアプリを作っていこうと思います。Realmの読み方は「レルム」、ライセンスはApacheです。

arrow-right
Atlas Device SDK is an offline-first, cloud-syncable database for mobile, web, desktop, and IoT apps.

では、いきましょう

手順

1.まずはプロジェクトを作成して、podで該当ライブラリをインストール&xcworkspaceを起動します。

pod 'RealmSwift'

2.storyboardでUIを作っていきます。

  • View Controllerを選択した状態で、メニューの「Editor → Embed In → Navigation Controller」を実行
  • View ControllerにTable Viewをのせる
  • Table ViewにTable View Cellをのせる。identifierに「Cell」を設定
  • View Controllerの右上(Navigationの部分)にBar Button Itemを追加。System Itemを「Add」(+マーク)に設定
  • 新しいView Controllerを追加。Text FieldとButtonをのせる
  • Bar Button Item(+マーク)からcontrolキーを押しながら、新しいView Controllerにドラック&ドロップして、遷移方法は「Show」を設定
  • (ここはstoryboardじゃないですが)メニューの「File → NEW → File」のCocoa Touch ClassでAddTaskViewController.swiftを追加
  • 新しいView ControllerのClassに「AddTaskViewController.swift」を設定

実行するとstoryboardは下記のようになります。

3.モデルクラスの作成

  メニューの「File → NEW → File」のSwift FileでTaskModel.swiftを追加

import Foundation
import RealmSwift

class TaskModel: Object {
    @objc dynamic var taskName = ""
}

4.View Controller.swiftを修正

import UIKit
import RealmSwift

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    @IBOutlet var taskTableView: UITableView!
    
    var taskList: Results<TaskModel>!
    var realm = try! Realm()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.taskTableView.delegate = self
        self.taskTableView.dataSource = self
        
        // Realmのデータを取得
        self.taskList = realm.objects(TaskModel.self)
        
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        self.taskTableView.reloadData()
        
    }

    // データ数を設定
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.taskList.count
    }
    
    // セルにデータを設定
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell =  self.taskTableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let task = self.taskList[indexPath.row]
        cell.textLabel?.text = task.taskName
        
        return cell
        
    }
    
    // セルの編集許可
    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }
    
    // スワイプしてセルを削除
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        
        // Realmのデータ削除
        try! realm.write {
            realm.delete(taskList[indexPath.row])
        }
        
        // テーブルのデータ削除
        self.taskTableView.deleteRows(at: [indexPath], with: .automatic)
        
    }
    
}

5.AddTaskViewController.swiftを修正

import UIKit
import RealmSwift

class AddTaskViewController: UIViewController {
    
    @IBOutlet var taskTextField: UITextField!
    
    var realm = try! Realm()

    override func viewDidLoad() {
        super.viewDidLoad()

    }
    
    @IBAction func addTask(_ sender: Any) {
        
        // 保存するためのTaskModeに入力した値を設定
        let task = TaskModel()
        task.taskName = self.taskTextField.text!
        
        // Realmにデータ登録
        try! realm.write {
            realm.add(task)
        }
        
        // Navigationcontrollerで前の画面に戻る
        self.navigationController?.popViewController(animated: true)
        
    }
    
}

6.storyboardとソースコードの紐付け

  • View Controller.swiftのtaskTableView
  • AddTaskViewController.swiftのtaskTextFieldとaddTask

以上で完了です。

+マークからタスクの追加ができます。あと、テーブルビューのセルをスライドするとデータの削除ができます。

アプリを再起動してもデータは残っているので、これで永続化ができました!

ただ、削除するとデータの並びが変わる。。。原因はいつか調べてみます。。。(どなたか教えていただけると助かります)

コメント