只能从属于 Swift 的 Realm 中删除一个对象

时间:2021-03-29 21:56:36

标签: ios swift realm

我正在尝试从我的 NotesApp 中的 Realm 中删除笔记,并遇到此错误:“只能从它所属的 Realm 中删除一个对象”。这个笔记之前也保存在 Realm 和 可以通过点击我的 FSCalendar 中的日期在我的 TableView 中显示它。我试图用realm.create(item)替换realm.add(item),但也得到了错误:“无法将'T'类型的值转换为预期的参数类型'Object.Type'(又名'RealmSwiftObject.Type') ”。我是编程新手,所以任何帮助将不胜感激。下面是相关的代码代码:

in my ToDoListItem.swift

class ToDoListItem: Object {
@objc dynamic var noteName: String = ""
@objc dynamic var date: Date =  Date()
@objc dynamic var descriptionText: String = ""
@objc dynamic var noteImage = Data()

init(date: Date, noteName: String) {
    self.date = date
    self.noteName = noteName
}

override init() {
    self.noteName = ""
    self.date = Date()
    self.descriptionText = ""
    self.noteImage = Data()
}

}

in my RealmManager.swift

class RealmManager {

static let shared = RealmManager()
private let realm = try! Realm()

func write<T: Object>(item: T) {
    realm.beginWrite()
    realm.add(item)
    try! realm.commitWrite()
}

func getObjects<T: Object>(type: T.Type) -> [T] {
    return realm.objects(T.self).map({ $0 })
}

func delete<T: Object>(item: T) {

    try! realm.write {
        realm.delete(item)
    }
}

}

in my ViewController where i can edit and delete the notes

@IBAction func didTapDelete() {
    
    let note = ToDoListItem()
    RealmManager.shared.delete(item: note)
    
    self.deletionHandler?()
    navigationController?.popToRootViewController(animated: true)
}

and finally in my TableViewController where the notes are displayed  (honestly i think the problem is hidden here but cannot find it...

@IBOutlet var tableViewPlanner: UITableView!
@IBOutlet var calendarView: FSCalendar!

private var data = [ToDoListItem]()

var datesOfEvents: [String] {
    return self.data.map { DateFormatters.stringFromDatestamp(datestamp: Int($0.date.timeIntervalSince1970)) }
}

var items: [ToDoListItem] = []

func getCount(for Date: String) -> Int {
    var count: [String : Int] = [:]
    for date in datesOfEvents {
        count[date] = (count[date] ?? 0) + 1
    }
    return count[Date] ?? 0
}

func getEventsForDate(date: Date) -> [ToDoListItem] {
    let string = DateFormatters.stringFromDatestamp(datestamp: Int(date.timeIntervalSince1970))
    return self.data.filter {DateFormatters.stringFromDatestamp(datestamp: Int($0.date.timeIntervalSince1970)) == string }.sorted(by: {$0.date < $1.date})
}

override func viewDidLoad() {
    super.viewDidLoad()
    
    calendarView.rounding()
    tableViewPlanner.rounding()
    
    data = RealmManager.shared.getObjects(type: ToDoListItem.self)
    self.items = self.getEventsForDate(date: Date())
    
    calendarView.delegate = self
    calendarView.dataSource = self
    tableViewPlanner.delegate = self
    tableViewPlanner.dataSource = self
    
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true)
    
    self.calendarView.select(Date())
    self.calendarView.reloadData()
    refresh()
}

//MARK:- TableView Data Source
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.items.count //data.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: K.plannerCellIdentifier, for: indexPath) as! NoteTableViewCell
    let note = self.items[indexPath.row]
    cell.configureCell(note: note)
    
    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
    
    let note = data[indexPath.row]
    guard
        let vc = storyboard?.instantiateViewController(identifier: K.infoVCIdentifier) as? InfoViewController else { return }
    vc.note = note
    vc.deletionHandler = { [weak self] in
        self?.refresh()
    }
    vc.title = note.noteName
    navigationController?.pushViewController(vc, animated: true)
}

//MARK:- User Interaction
@IBAction func didTapAddButton() {
    guard
        let vc = storyboard?.instantiateViewController(identifier: K.entryVCIdentifier) as? EntryViewController else { return }
    vc.completionHandler = { [weak self] in
        self?.refresh()
    }
    vc.title = K.entryVCTitle
    navigationController?.pushViewController(vc, animated: true)
}

func refresh() {
    
    DispatchQueue.main.async {
        self.data = RealmManager.shared.getObjects(type: ToDoListItem.self)
        self.tableViewPlanner.reloadData()
        self.calendarView.reloadData()
    }
}

}

扩展 PlannerViewController:FSCalendarDelegateAppearance & FSCalendarDataSource {

func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, eventDefaultColorsFor date: Date) -> [UIColor]? {
    let dateString = DateFormatters.yearAndMonthAndDateFormatter.string(from: date)
    if self.datesOfEvents.contains(dateString) {
        return [UIColor.blue]
    }
    return [UIColor.white]
}

func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
    self.items = self.getEventsForDate(date: date)
    self.tableViewPlanner.reloadData()

}

func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
    let dateString = DateFormatters.yearAndMonthAndDateFormatter.string(from: date)
    let count = self.getCount(for: dateString)
    self.tableViewPlanner.reloadData()
    return count
}

}

1 个答案:

答案 0 :(得分:0)

真正的问题是 didTapDelete 函数——你为什么要创建一个新的笔记只是为了删除它(我希望它只是为了测试领域删除语法)。您应该删除传递给视图控制器以进行编辑/删除的注释对象。 (vc.note 中确实选择了行 -> self.note 在另一个 VC 中 - didTapDelete 在哪里) 所以你没有点击删除看起来像-

RealmManager.shared.delete(item: note)
//show deleted alert & go back

对错误的一点解释 - 仅实例化 Realm 对象 (ToDoListItem()) 不会将其添加到 Realm(数据库系统)。要删除/编辑领域对象,必须从领域 (RealmManager.shared.getObjects(type: ToDoListItem.self)) 获取或添加到领域。

我建议在跳入代码之前先阅读 Realm 教程(有很多)