2017-04-25 126 views
7

我在学习如何使用Realm Swift和Charts,这样我最终可以在我正在构建的应用程序中使用它们,并且我正在搞定一段时间领域。最终,我计划让Charts查看我的Realm DB,然后根据数据显示图表,但在此之前,我需要检查是否存在领域对象(如果不存在),以创建然后当用户使用该应用程序时,将“计数”添加到该记录并相应地更新图表。如何更新realm中的对象swift

正如我正在学习,我已经把它分解成几个步骤。我已经想通了如何检查,看是否有记录存在,如果不这样构建它:

我的境界型号:

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文档和更多的Google搜索来做到这一点。这是我已经有了,但它不工作:

@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:

终止应用程序由于未捕获的异常“值无效',原因:类型为'WorkoutsCount'的对象的类型日期属性'date'的预期对象,但收到:2017-04-24 07:00:00 +0000'

+0

为什么你不使用主键?当您想要更新现有对象时,它就是为这些场景设计的。使用它比删除和重新创建对象更方便,同时它也是一个更优化的解决方案。 –

+0

因为当返回并添加一个主键时,它打破了我已经有的工作,在第一组代码中的“let realm = try!Realm()”行出错,我无法弄清楚解决这个问题。由于我花了一天时间才完成这项工作,感觉我正在退步。 – jammyman34

+0

您是否向您的AppDelegate applicationDidFinishLaunching方法添加了迁移块? 如果不是这样,那就是您出现错误的原因,每次更改Realm模型时都会得到相同的错误。 –

回答

20

更新对象只是分配写入事务中的属性的值。看我们的文档。

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 
    } 
} 

供参考:请不要在查询中使用字符串插值。通常通过字符串插值构造一个重要的字符串是不好的做法使用NSPredicate的字符串替代语法,如filter("date = %@", removeTodaysItem)

+0

是否有一种方法来设置'workouts'var,以便使用CONTAIN进行过滤因为我一直在尝试使用Predicates并且文档不明确,所以我无法弄清楚该语法,因此我不能弄清楚要么...我意识到'不要使用字符串插值'这一点,但我绝望,这些都是我在网上找到的例子,但谢谢澄清:) – jammyman34