0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

RealmSwiftを使ってみる

Posted at

必要最小限のアプリでRealmSwiftを試してみる

今日は、RealmSwiftを初めて使ってみます。
まずは動かしてみたいので、必要最小限の「ToDoアプリ」にRealmSwiftを追加して、変更内容が保存されたら成功とします。

ToDoアプリ(RealmSwift追加前)

ContentView
import SwiftUI

struct RoundedButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .padding(EdgeInsets(
                top: 7, leading: 10, bottom: 7, trailing: 10
            ))
            .foregroundColor(.white)
            .background(.blue)
            .cornerRadius(7)
            .opacity(configuration.isPressed ? 0.5 : 1)
    }
}


struct ContentView: View {
    @State var inputTitle: String = ""
    @State var toDoList = ["猫に餌をやる", "雨戸を開ける", "洗濯をする"]
    
    var body: some View {
        VStack {
            TextField("やることを入力", text: $inputTitle)
                .textFieldStyle(.roundedBorder)
                .padding(EdgeInsets(
                top: 10, leading: 10, bottom: 5, trailing: 10
                ))
            
            Button(action: {
                if !inputTitle.isEmpty {
                    toDoList.append(inputTitle)
                    inputTitle = ""
                } 
            }, label: {
                Text("追加")
            })
            .buttonStyle(RoundedButtonStyle())
            
            List {
                ForEach(toDoList, id: \.self) { toDo in
                    Text(toDo)
                } // ForEach
                .onDelete(perform: deleteTitles)
            } // List
        } // VStack
        
    } // body
    
    func deleteTitles(at offsets: IndexSet) {
        toDoList.remove(atOffsets: offsets)
    }
} // ContentView

配列をListで表示して、やることの追加と削除だけできるようにした、シンプルなアプリです。

ToDoスクショ.png

ここにRealmSwiftを追加して、ToDoリストの内容を変更した後にアプリを落としても、変更内容が保存されているようにしていきます。

テーブル定義クラスを追加

ToDo
import Foundation
import RealmSwift

class ToDo: Object, ObjectKeyIdentifiable {
    @Persisted(primaryKey: true) var id: UUID = UUID()
    @Persisted var title: String = ""
}

ToDo.swiftを作成して、データベースのテーブル定義を設定したクラス作ります。
カラムに当たるプロパティには、@Persistedを付与します。

ViewModelクラスを追加

ToDoViewModel
import Foundation
import RealmSwift

// ViewModel
class ToDoViewModel: ObservableObject {
    private var realm: Realm
    @Published var toDoList: [ToDo] = []

    init() {
        do {
            realm = try Realm()
            loadToDos()
        } catch {
            print("Failed to open Realm. Error: \(error.localizedDescription)")
            realm = try! Realm(configuration: .init(inMemoryIdentifier: "TemporaryRealm"))
        }
    }

    func loadToDos() {
        let todos = realm.objects(ToDo.self)
        toDoList = Array(todos)
    }

    func addToDo(title: String) {
        let newToDo = ToDo()
        newToDo.title = title

        do {
            try realm.write {
                realm.add(newToDo)
            }
            loadToDos()
        } catch {
            print("Failed to add ToDo. Error: \(error.localizedDescription)")
        }
    }

    func deleteToDos(at offsets: IndexSet) {
        offsets.map { toDoList[$0] }.forEach { toDo in
            do {
                try realm.write {
                    realm.delete(toDo)
                }
            } catch {
                print("Failed to delete ToDo. Error: \(error.localizedDescription)")
            }
        }
        loadToDos()
    }
}

Realmデータベースを使用して、アプリケーションのToDoリストの管理を行うためのToDoViewModelクラスを作成します。

ContentViewを変更

ContentView
import SwiftUI

struct RoundedButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .padding(EdgeInsets(
                top: 7, leading: 10, bottom: 7, trailing: 10
            ))
            .foregroundColor(.white)
            .background(.blue)
            .cornerRadius(7)
            .opacity(configuration.isPressed ? 0.5 : 1)
    }
}

struct ContentView: View {
    @State var inputTitle: String = ""
-    @State var toDoList = ["猫に餌をやる", "雨戸を開ける", "洗濯をする"]
+    @StateObject private var viewModel = ToDoViewModel()
    
    var body: some View {
        VStack {
            TextField("やることを入力", text: $inputTitle)
                .textFieldStyle(.roundedBorder)
                .padding(EdgeInsets(
                top: 10, leading: 10, bottom: 5, trailing: 10
                ))
            
            Button(action: {
                if !inputTitle.isEmpty {
-                    toDoList.append(inputTitle)
+                    viewModel.addToDo(title: inputTitle)
                    inputTitle = ""
                } 
            }, label: {
                Text("追加")
            })
            .buttonStyle(RoundedButtonStyle())
            
-            List {
-               ForEach(toDoList, id: \.self) { toDo in
-                    Text(toDo)
-                } // ForEach
-                .onDelete(perform: deleteTitles)
-            } // List
            
+             List {
+                ForEach(viewModel.toDoList) { toDo in
+                    Text(toDo.title)
+                } // ForEach
+                .onDelete(perform: viewModel.deleteToDos)
+            } // List

         } // VStack
         
    } // body
    
    func deleteTitles(at offsets: IndexSet) {
        toDoList.remove(atOffsets: offsets)
    }
} // ContentView

最後に、ContentView.swiftの中でToDoViewModelクラスをインスタンス化して、ToDoViewModelに定義したメソッドでリストの追加・削除を行うように書き換えます。

ToDoスクショ2.png

アプリの起動中に追加・削除を行なったリストの内容が、アプリ停止後に再起動しても保存されています!

ご覧いただき、ありがとうございました。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?