2017-04-25 12 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) 
     } 
    } 

私が確認したことレルムブラウザを介して彼の作品アプリ。

次にTo-Doリストには、「今日の日付のレコード」のレコードを更新する方法がわかります。これを行うには、ボタンを作成しました。タップすると、これを実行しようとします。私はグーグルでグーグルグーグルしていて、私のモデルでプライマリキーを使用しないので、問題の特定のレコードを最初に削除してから新しいデータを追加する必要があるので、考え始めました。私の人生では、Realmのドキュメントやさらにグーグル・グーグルに基づいてこれを行う方法を理解できません。それは動作しませんが、これは、私が持っているものです:

@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'プロパティのタイプdateの予想オブジェクトですが、受け取った:2017-04-24 07:00:00 +0000 '

+0

なぜプライマリキーを使用しないのですか?既存のオブジェクトを更新する場合に、これらのシナリオのために設計されています。オブジェクトを削除して再作成するよりも使いやすく、さらに最適なソリューションです。 –

+0

元のキーに戻って追加したときに、すでに作業していたものが壊れてしまったため、上記のコードの最初のコードセットで「realm = try!Realm()」行にエラーがあり、それを修正する。それが働くには1日かかりましたので、私は後退しているように感じました。 – 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 
    } 
} 

FYI:クエリで文字列補間を使用しないでください。一般的に、文字列補間によって重要な文字列を構築するのは悪い習慣です。 filter("date = %@", removeTodaysItem)のようなNSPredicateの文字列置換構文を使用します。

+0

には 'workouts' varを設定する方法があるので、CONTAINでフィルタリングします。私は述語で作業しようとしているので、構文を理解できませんでした。どちらかといえば...私は「文字列補間を使用しない」ビットについても認識していましたが、私は必死であり、それらはオンラインで検索した例でしたが、わかりました:) – jammyman34

関連する問題