swift初心者です。
swiftuiを使用してます。
データの削除をしようとしているのですが、
「Object has been deleted or invalidated.」が出てしまいます。
原因がわかりません。
教えていただきたいです。
また、
realmを見てもデータが登録されないのですが、
なぜでしょうか?
他に追記があった方がいい場合は追記いたします。
・View
import SwiftUI // MARK: UserListView struct UserView: View { @ObservedObject var viewModel = UserViewModel() @State private var isUserTextFieldPresented = false @State private var isDeleteAlertPresented = false @State private var isDeleteAllAlertPresented = false @State private var userTextField = "" var body: some View { NavigationView { VStack { if (isUserTextFieldPresented) { TextField("メモを入力してください", text: $userTextField) .textFieldStyle(DefaultTextFieldStyle()) .keyboardType(.asciiCapable) } List { ForEach(viewModel.users.sorted { $0.postedDate > $1.postedDate }, id: \.self) { user in HStack { UserRowView(user: user) Spacer() // Buttonにすると行全体にタップ判定がついてしまったので、Text.onTapGestureを代わりに使っている Text("削除").onTapGesture { isDeleteAlertPresented.toggle() } .padding() .foregroundColor(.white) .background(Color.red) } .alert(isPresented: $isDeleteAlertPresented) { Alert(title: Text("警告"), message: Text("メモを削除します。\nよろしいですか?"), primaryButton: .cancel(Text("いいえ")), secondaryButton: .destructive(Text("はい")) { viewModel.deleteUser = user } ) } } } } .navigationTitle("メモの一覧") .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("追加") { if (isUserTextFieldPresented) { viewModel.userTextField = userTextField userTextField = "" } isUserTextFieldPresented.toggle() }.disabled(isUserTextFieldPresented && userTextField.isEmpty) } } } } } // MARK: UserRowView struct UserRowView: View { var user: User var body: some View { VStack(alignment: .leading) { Text(formatDate(user.postedDate)) .font(.caption) .fontWeight(.bold) Text(user.userName) .font(.body) } } func formatDate(_ date : Date) -> String { let formatter = DateFormatter() formatter.dateStyle = .long formatter.timeStyle = .medium formatter.locale = Locale(identifier: "ja_JP") return formatter.string(from: date) } }
・ViewModel
import Foundation import Combine import RealmSwift class UserViewModel: ObservableObject { @Published private(set) var users: [User] = Array(User.findAll()) @Published var userTextField = "" @Published var deleteUser: User? @Published var isDeleteAllTapped = false private var addUserTask: AnyCancellable? private var deleteUserTask: AnyCancellable? init() { addUserTask = self.$userTextField .sink() { username in guard !username.isEmpty else { return } let user = User() user.userName = username self.users.append(user) User.add(user) } deleteUserTask = self.$deleteUser .sink() { user in guard let user = user else { return } if let index = self.users.firstIndex(of: user) { do{ self.users.remove(at: index) User.delete(user) }catch { print("Error \(error)") } } } } }
・User
import Foundation import RealmSwift class User: Object { //ユーザID @objc dynamic var id: Int = 0 //ユーザ名 @objc dynamic var userName: String = "" @objc dynamic var postedDate = Date() //Primary Keyの設定 override static func primaryKey() -> String? { return "id" } } extension User { private static var config = Realm.Configuration(schemaVersion: 1) private static var realm = try! Realm(configuration: config) static func findAll() -> Results<User> { realm.objects(self) } static func add(_ user: User) { try! realm.write { realm.add(user, update: .all) } } static func delete(_ user: User) { try! realm.write { realm.delete(user) } } }
すみません、再現確認してなくて、コードを眺めただけなのですが、
Userのidは初期値の0以外に設定しているところはありますでしょうか?
質問ありがとうございます。
Userのidは載せているコードの部分でしか設定していません。
コメントありがとうございます。
> 「Object has been deleted or invalidated.」
> realmを見てもデータが登録されないのですが、
Realmについてあまり詳しくなくて、見当違いなことを書いてしまうかもしれませんが、
idが主キーになっているものの、
全てのデータが0なので、
正しく登録できなそうな気がしました。
登録されていないのであれば、削除することもできないのかな、と思いました。
*一般的に主キーは一意という印象から書いています・・
なるほどですね!
ありがとうございます!
確認してます!
回答1件
あなたの回答
tips
プレビュー