iPhone
 Computer >> コンピューター >  >> スマートフォン >> iPhone

SwiftでRealmデータベースをiOSアプリに導入する方法|CRUD操作を学べるToDoアプリ開発ガイド

こんにちは!この記事では、RealmデータベースをiOSアプリに追加する方法を解説します。

シンプルなToDoアプリを作りながら、RealmデータベースにおけるCRUD(Create=作成、Read=読み取り、Update=更新、Delete=削除)操作の実装方法を学んでいきましょう。

Realmとは?

SwiftでRealmデータベースをiOSアプリに導入する方法|CRUD操作を学べるToDoアプリ開発ガイド

Realmは、開発者にとって扱いやすく使い勝手の良いオープンソースのモバイル向けデータベースです。iOSアプリではCore Dataの代替として利用することもできます。

Realmはクロスプラットフォーム対応のモバイルデータベースです。そのため、ネイティブのAndroid・iOSアプリはもちろん、React Nativeなどで構築されたクロスプラットフォームアプリでも使用できます。対応言語はObjective-C、Swift、Java、Kotlin、C#、JavaScriptと幅広いのが特徴です。

iOSプロジェクトへのRealmのセットアップ方法

RealmをiOSプロジェクトに追加するには、SPM(Swift Package Manager)、CocoaPods、Carthageのいずれかを使用できます。ここではCocoaPodsを使って、Realm PodをiOSプロジェクトに追加していきます。

  1. Xcodeを開き、Core Dataを使用しないUIKit+Swiftの空のiOSアプリプロジェクトを作成します。
  2. 次にXcodeを閉じ、ターミナルを開きます。ターミナルでプロジェクトのディレクトリへ移動してください。
  3. 以下のコマンドを実行してPodfileを作成します。
pod init

4. ディレクトリの中身を確認すると、新しいPodfileが生成されていることがわかります。任意のテキストエディタ(ここではVimを使用)でファイルを開き、下の画像のように編集しましょう。編集が完了したら保存してPodfileを閉じます。

SwiftでRealmデータベースをiOSアプリに導入する方法|CRUD操作を学べるToDoアプリ開発ガイド

これでRealm DBへの依存関係が定義できたので、以下のコマンドを実行して依存関係をインストールします。

pod install
SwiftでRealmデータベースをiOSアプリに導入する方法|CRUD操作を学べるToDoアプリ開発ガイド

ご覧のとおり、iOSプロジェクトにRealm DBの依存関係を正常に追加できました。続いて、以下のコマンドを実行してXcodeでプロジェクトを開きます。

open YOUR_APP_NAME.xcworkspace

注意:Xcodeを開いたら、必ずCommand+Bキーでプロジェクトをビルドしておきましょう。

ユーザーインターフェースの設計方法

アプリのUIはシンプルに保ちます。Main.storyboardを開き、プロトタイプセル付きのテーブルビューを配置して、下図のようなシンプルなUIを作成します。その後、Navigation Controllerを埋め込み、ViewController.swiftファイル内にテーブルビュー用のIBOutletを作成してください。

SwiftでRealmデータベースをiOSアプリに導入する方法|CRUD操作を学べるToDoアプリ開発ガイド

Realmでのデータモデル作成方法

今回のToDoアプリでは、各タスクは「タスク名」と「タスクID」を持つものとします。ToDoタスクを表すModelクラスを作成しましょう。プロジェクトナビゲーターで右クリックして新しいSwiftファイルを作成し、以下のコードを追加します。

import Foundation
import RealmSwift


class ToDoTask:Object
{
    @objc dynamic var tasknote: String?
    @objc dynamic var taskid: String?
}

ここでは「ToDoTask」というモデルクラスを作成しました。このクラスは、RealmDBに付属するObjectクラスを継承しています。Objectクラスは、このモデルクラスで作成したデータをデータベースに保存する際の内部処理をすべて担ってくれます。

また、2つのプロパティを追加しました。tasknoteは実行すべきタスクの内容、taskidはタスクの識別子で、どちらもString型です。@objcはSwiftコードをObjective-Cから参照可能にするための属性で、dynamicはObjective-Cの動的ディスパッチを使用することを意味します。

基本的なCRUD機能の実装

今回のアプリは、以下の機能を実装します。

  1. UIAlertControllerを使ってユーザーから入力を受け取る。
  2. 入力内容をデータベースとテーブルビューの両方に追加する。
  3. ユーザーが入力内容を編集できるようにする。
  4. 行をスワイプして削除すると、テーブルビューとデータベースの両方からデータを削除する。
  5. アプリ起動時にデータベースから全データ(存在する場合)を取得し、テーブルビューに表示する。

UIAlertControllerでユーザー入力を取得する方法

ViewController.swiftを開き、viewDidLoad()メソッド内に以下のコードを追加します。さらに、addTask()という新しい関数を作成し、テキストボックス付きのアラートビューコントローラーを表示してユーザー入力を受け取るコードを記述します。

右上のバーボタンが押されるとaddTask()関数が呼び出され、テキストフィールド付きのalertviewcontrollerが表示されてユーザー入力を受け取れるようになります。

navigationItem.rightBarButtonItem = UIBarButtonItem(image: .add, style: .done, target: self, action: #selector(addTask))

navigationController?.navigationBar.prefersLargeTitles = true

title = "RealmDB"
@objc
    func addTask()
    { 
        let ac = UIAlertController(title: "Add Note", message: nil, preferredStyle: .alert)
        
        ac.addTextField(configurationHandler: .none)
        
        ac.addAction(UIAlertAction(title: "Add", style: .default, handler: { (UIAlertAction) in
          
              if let text = ac.textFields?.first?.text
            {
                print(text)
            }
            
        }))
        ac.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
        present(ac, animated: true, completion: nil)
    }

入力内容をデータベースとテーブルビューに追加する方法

Realmにデータを保存するには、まずRealmのインスタンスを取得する必要があります。このインスタンスを通じて、CRUD操作に必要なすべてのメソッドにアクセスできます。ViewController.swiftファイルにRealm型のプロパティを作成し、viewDidLoad()メソッド内で初期化しましょう。

 var realmDB: Realm!
 override func viewDidLoad() {
        super.viewDidLoad()
        
        navigationItem.rightBarButtonItem = UIBarButtonItem(image: .add, style: .done, target: self, action: #selector(addTask))
        navigationController?.navigationBar.prefersLargeTitles = true
        title = "RealmDB"
        
        realmDB = try! Realm()
       
    }

次に、データモデル(ToDoTask)型の空の配列を作成します。この配列には、テーブルビューとデータベースに追加されるすべてのタスクが格納されます。

そして、addTask()関数内のAddアクションのクロージャを修正し、ユーザーの入力を取得してランダムなIDを生成し、配列に追加したうえでデータベースに保存するようにします。

var tasks = [ToDoTask]()
 if let text = ac.textFields?.first?.text
            {
            	//データモデル配列にデータを追加
                let t = ToDoTask()
                t.taskid = UUID().uuidString
                t.tasknote = text
                self.tasks.append(t)
                
                //データベースにデータを追加
                try! self.realmDB.write {
                    self.realmDB.add(t)
                }
                //テーブルビューのUIを更新
                self.tasktv.reloadData()
            }

この時点でアプリを実行すると、データはデータベースに保存されます。しかし、デリゲートメソッドを実装していないため、テーブルビューには表示されません。

そこで、ViewControllerクラスにUITableViewDelegateUITableViewDataSourceのプロトコルを実装し、プロトコルのスタブを追加しましょう。

numberOfRowsInSectionメソッド内では、tasks配列の要素数を返します。これにより、テーブルビューに表示される行数がtasks配列の要素数と一致します。

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: 
 Int) -> Int 
 {
        return tasks.count;
 }

次に必要なのは、各行に表示するコンテンツの指定です。これはcellForRowAtデリゲートメソッドで実現できます。ストーリーボードで指定した識別子を使ってセルをdequeueし、ラベルのテキストとしてtasks配列の該当要素のtasknoteプロパティを設定します。

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
        {
            cell.textLabel?.text = tasks[indexPath.row].tasknote
            return cell
        }
        return UITableViewCell()
    }

ユーザーが入力内容を編集できるようにする方法

次に、ユーザーが入力済みのタスクを編集し、その変更をデータベースとUIの両方に反映できるようにします。これは、ユーザー入力を取得する際と同様の手法で実装できます。didSelectRowAtデリゲートメソッドを実装すると、ユーザーがテーブルビューの行をタップしたときに呼び出されます。

以下のコードを追加すると、テキストビュー付きのAlertViewControllerが表示されます。入力されたテキストでセルの内容を更新すると同時に、データベースの内容も更新されます。

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let tasktomodify = tasks[indexPath.row]
        let ac = UIAlertController(title: "Update task", message: nil, preferredStyle: .alert)
        
        ac.addTextField(configurationHandler: .none)
        ac.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (UIAlertAction) in
            if let text = ac.textFields?.first?.text
            {
                if(!text.isEmpty)
                {
                try! self.realmDB.write({
                    tasktomodify.tasknote = text
                })
                self.tasktv.reloadData()
                }
            }
        }))
        
        present(ac, animated: true, completion: nil)
    }

スワイプで行を削除し、テーブルビューとデータベースの両方からデータを削除する方法

ここでは、テーブルビューに「スワイプで削除」機能を実装し、ユーザーがタスクを削除できるようにします。内部的には、ユーザーがテーブルビューの行をスワイプして削除したときに、データベースからデータを削除し、データモデル配列からも削除して、テーブルビューのUIを更新する必要があります。

これはcommit editingStyleデリゲートメソッドを実装し、以下のコードを追加することで実現できます。

 func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete
        {
            let tasktoDelete = tasks[indexPath.row]
            try! realmDB.write({
                realmDB.delete(tasktoDelete)
                self.tasks.remove(at: indexPath.row)
                self.tasktv.deleteRows(at: [indexPath], with: .fade)
            })
        }
    }

データベースから全データを取得してテーブルビューに表示する方法

最後に、Read操作を実装します。ユーザーがアプリを起動するたびに、データベースからデータ(存在する場合)を取得し、テーブルビューに表示するようにします。

これは、ビューコントローラーのSwiftファイルにgetTodo関数を作成し、その中に以下のコードを追加することで実現できます。

func getTodos()
    {
       //データベースから全データを取得
        let notes = realmDB.objects(ToDoTask.self)
        
        //重複を防ぐためにモデルデータ配列をクリア
        self.tasks.removeAll()
        
        /*取得したデータが空でない場合は、モデルデータ配列に追加してUIを更新*/
        if(!notes.isEmpty)
        {
        for n in notes
        {
            
            self.tasks.append(n)
            
        }
            self.tasktv.reloadData()
        }
        
        
    }

おまけ:iOSシミュレーターのデータベース内容を確認する方法

ここまででアプリを実行すると、期待どおりに動作していることが確認できます。しかし、データが本当にデータベースに保存されているのか、どうやって確認すればよいのでしょうか? そこで活躍するのが「MongoDB Realm Studio」というアプリです。これを使えば、シミュレーターのRealmデータベースに保存されたデータを閲覧できます。

なお、この方法はiOSシミュレーターでアプリをテストしている場合にのみ有効です。

viewDidLoad()メソッドに以下のコードを追加すると、アプリの実際のファイルパスが出力されます。

 print(realmDB.configuration.fileURL!)
SwiftでRealmデータベースをiOSアプリに導入する方法|CRUD操作を学べるToDoアプリ開発ガイド

コンソールに出力されたファイルパスをコピーし、ターミナルを開いて以下のコマンドを実行します。

open REALM_FILE_PATH_HERE
上記のコマンドを実行する前に、MongoDB Realm Studioをブラウザからダウンロードしておいてください。

すると、アプリのRealmファイルがMongoDB Realm Studioで開かれ、データベースに保存されたデータがテーブル形式で表示されます。

タスクの編集や削除などでデータに変更を加えると、その変更はMongoDB Realm Studioにも反映されます。

SwiftでRealmデータベースをiOSアプリに導入する方法|CRUD操作を学べるToDoアプリ開発ガイド

おめでとうございます! これで、iOSアプリでCRUD操作を実装したシンプルなアプリが完成しました。

  1. iOS 11のポッドキャストアプリの使い方 – 新機能を徹底解説

    Appleはついに「Podcast」アプリの刷新が必要であることに気づき、iOS 11で同アプリに新たな命を吹き込みました。待ち望まれていたビジュアルのアップデートにより、デザインがより魅力的になり、ポッドキャストの追加や視聴がこれまで以上に簡単になりました。さらに、あなたの好みを学習するにつれて、おすすめのポッドキャストを自動的に提案してくれるようにもなっています。新機能は制作者とリスナーの両方にとって嬉しい内容となっています。革新的なタブデザインアプリを起動して最初に気づくのは、画面下部に追加された4つの新しいタブです。タブは「今すぐ聴く」「ライブラリ」「見る」「検索」の4つ構成で、「検索

  2. iOS 11の写真アプリで「人」を追加・削除する方法

    iOS 10では、写真に写った人物の顔を自動認識し、人物ごとに写真を整理できる革新的な機能が導入されました。これにより、大切な人の写真を見たいときに、膨大な写真をめくる必要はなくなり、その人のサムネイルをタップするだけで関連する写真を一覧できるようになりました。しかし、iOS 11では数多くの変更や改良が加えられ、その一部は従来の使い勝手からの変化を感じさせるものでした。そのひとつが、「人」のサムネイルを追加するオプションへの直接アクセスができなくなった点です。そこで本記事では、iOS 11を搭載したiPhoneの写真アプリで、人物を追加・削除する具体的な手順をご紹介します。写真アプリに人物を