как обновить объект в realm swift
Я пытаюсь научиться использовать Realm Swift и диаграммы, чтобы в конечном итоге использовать их в приложении, которое я создаю, и у меня есть адское время, выясняя Realm. В конце концов, я планирую, чтобы диаграммы смотрели на мою БД Realm, а затем отображали диаграммы на основе данных, но прежде чем я это сделаю, Мне нужно проверить, существует ли объект realm, если он этого не делает, чтобы создать его, а затем, когда пользователь использует приложение, добавить "счетчики" к этой записи и обновить диаграмму соответственно.
Как я узнаю, я разбил это на шаги. Я уже выяснил, как проверить, существует ли запись, и если нет, то построить ее так:
Моя Модель Realm:
class WorkoutsCount: Object{
dynamic var date: Date = Date()
dynamic var count: Int = Int(0)
}
// function to check if this weeks days have been created in Realm DB yet and creates them if not
let realm = try! Realm()
lazy var workouts: Results<WorkoutsCount> = { self.realm.objects(WorkoutsCount.self)}()
let startOfWeekDate = Date().startOfWeek(weekday: 1)
let nextDay = 24 * 60 * 60
// checks the DB to see if it contains the start of this week
func searchForDB(findDate: Date) -> WorkoutsCount?{
let predicate = NSPredicate(format: "date = %@", findDate as CVarArg)
let dateObject = self.realm.objects(WorkoutsCount.self).filter(predicate).first
if dateObject?.date == findDate{
return dateObject
}
return nil
}
func setThisWeeksDays(){
//if the beginning of this week doesn't exist in the DB then create each day with 0's as the count data
if searchForDB(findDate: startOfWeekDate) == nil{
try! realm.write() {
let defaultWorkoutDates = [startOfWeekDate, startOfWeekDate + TimeInterval(nextDay), startOfWeekDate + TimeInterval(nextDay*2), startOfWeekDate + TimeInterval(nextDay*3), startOfWeekDate + TimeInterval(nextDay*4), startOfWeekDate + TimeInterval(nextDay*5), startOfWeekDate + TimeInterval(nextDay*6)]
for workouts in defaultWorkoutDates {
let newWorkoutDate = WorkoutsCount()
newWorkoutDate.date = workouts
self.realm.add(newWorkoutDate)
}
}
workouts = realm.objects(WorkoutsCount.self)
}
}
Я проверил, что его работы через приложение Realm Browser.
далее в моем списке дел, чтобы выяснить, как обновить запись для "сегодняшней записи даты". Для этого я создал кнопку, чтобы при нажатии она пыталась это сделать. Я гуглил поскольку я не использую первичный ключ в своей модели, я должен сначала удалить конкретную запись, о которой идет речь, а затем добавить ее снова с новыми данными. Я не могу понять, как это сделать, основываясь на документации Realm и еще больше на googling. Это то, что у меня есть, хотя это не работает:
@IBAction func btnUpdate1MW(_ sender: Any) {
if searchForDB(findDate: today) != nil{
if plusOne <= 7{
plusOne += 1
CounterImage1MW.image = UIImage(named: "1MWs-done-(plusOne)")
let realm:Realm = try! Realm()
// deletes the original item prior to being updated and added back below
let removeTodaysItem = today
let workout = realm.objects(WorkoutsCount.self).filter("date = '(removeTodaysItem)'")
if workout.count > 0{
for date in workout{
try! realm.write {
realm.delete(date)
}
}
}
// adds back the item with an updated count
do {
let realm = try Realm()
try realm.write {
realm.create(WorkoutsCount.self, value: ["date": today, "count": plusOne], update: false)
}
} catch let error as NSError {
fatalError(error.localizedDescription)
}
}
print("add to 1MW + 1")
}
}
когда я нажимаю кнопку btnUpdate1MW, я получаю следующую ошибку в Xcode:
прекращение приложения из-за неучтенное исключение "недопустимое значение", причина: "ожидаемый объект типа date для свойства "date" на объекте типа "WorkoutsCount", но полученный: 2017-04-24 07:00:00 +0000'
1 ответов
обновление объектов-это просто присвоение значения свойству в транзакции записи. Смотрите нашу документацию.
https://realm.io/docs/swift/latest/#updating-objects
поэтому вам не нужно удалять, а затем добавлять объект. Просто присвоить новое значение свойству в транзакции записи, как показано ниже.
let workouts = realm.objects(WorkoutsCount.self).filter("date = %@", removeTodaysItem)
let realm = try! Realm()
if let workout = workouts.first {
try! realm.write {
workout.date = today
workout.count = plusOne
}
}
FYI: пожалуйста, не используйте интерполяцию строк в запросе. Обычно построение важной строки с помощью Строковой интерполяции - это плохая практика. Используйте синтаксис замены строк NSPredicate, например filter("date = %@", removeTodaysItem)
.