I'm trying do delete the note from Realm in my NotesApp and facing this error: "Can only delete an object from the Realm it belongs to". This note has been saved before also in Realm and could display it in my TableView by tapping on the date in my FSCalendar. I tried to replace realm.add(item) with realm.create(item), but also got the error: "Cannot convert value of type 'T' to expected argument type 'Object.Type' (aka 'RealmSwiftObject.Type')". I'm new in programming, so any help would be appreciated. Here's the relevant code code:
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()
}
}
}
extension 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
}
}