2016-08-05 2 views
2

私はテーブルからデータを取り込むためにサーバーからいくつかのjsonデータを取得します。データが変更されている可能性があるので、毎回すべてのデータを取得します。そのデータをRealmオブジェクトにマップし、それをデータベースに保存します。一次IDは、重複を防ぐために使用されます。レルム:オブジェクトへの不必要な更新を防ぎます

レルム通知を使用して、テーブルビュー/コレクションビューをデータソースと同期させます。サーバー要求が完了すると、オブジェクトがデータベースに更新または追加され、ビューが自動的にリロードされます。

問題は、データベース内のすべてのオブジェクトが更新されるためです。実際には全く違いない場合でも、私は盲目的にrealm.add(object, update:true)を使用しているためです。 実際に変更されていないオブジェクトを更新しないで、セルを不必要に再ロードしないようにするよい方法はありますか?

私が試みた解決策は、同じプライマリIDを持つオブジェクトが存在するかどうかをチェックし、それらを比較し、それらが一致しない場合にオブジェクトを追加/更新する関数を含むレルムのオブジェクトクラスに拡張機能を書き込むことでした。しかし、私は多くのクラスのオブジェクトを持っています。オブジェクトの型をオブジェクト自体から取得する方法を見つけることができませんでした。

// All subclasses of ServerObject have id as their primaryKey 
let object = database.objectForPrimaryKey(type:???, key: self.id) 

私はそれがトラブルを求めていますので、私のクラスの一人一人にコードをチェックインする前には、追加の同じ塊をコピーしたくないので、私は、プロトコルや拡張子に行くことができる何かを必要とする、あるいは単にサーバーの応答を処理するための全く別の方法です。

答えて

1

あなたはの線に沿って何かをしたいようですね:

extension Object { 
    public func hasChanges(realm: Realm) -> Bool { 
     guard let obj = realm.objectForPrimaryKey(self.dynamicType, key: self["id"]) 
      else { return true } 

     for property in obj.objectSchema.properties { 
      let oldValue = obj[property.name] 
      let newValue = self[property.name] 

      if let newValue = newValue { 
       if oldValue == nil || !newValue.isEqual(oldValue) { 
        return true 
       } 
      } else if oldValue != nil { 
       return true 
      } 
     } 
     return false 
    } 
} 

これは、として使用することになります。ネストされたオブジェクト(リスト)を持つオブジェクトについて

let obj = MyObjectType() 
obj.id = ...; 
obj.field = ...; 
if obj.hasChanges(realm) { 
    realm.add(obj, update: true) 
} 
+0

これはまさに私が探しているものです!私は私の机に戻ってきたときにそれを撃つだろう。しかし完璧に見えます! – Erik

+0

もう1つ複雑です。リストであるプロパティをどのように処理できますか? newValueとoldValueがList の場合、リストが同じであってもisEqual()はfalseを返します。 – Erik

0

、この修正されたソリューションが動作するようですよく

// This function is general and can be used in any app 
private func hasChanges(realm: Realm) -> Bool { 
    guard let obj = realm.objectForPrimaryKey(self.dynamicType, key: self["id"]) 
     else { return true } 

    for property in obj.objectSchema.properties { 

     // For lists and arrays, we need to ensure all the entries don't have changes 
     if property.type == .Array { 
      let list = self.dynamicList(property.name) 
      for newEntry in list { 
       if newEntry.hasChanges(realm) { 
        return true 
       } 
      } 

     // For all properties that are values and not lists or arrays we can just compare values 
     } else { 

      let oldValue = obj[property.name] 
      let newValue = self[property.name] 

      if let newValue = newValue { 
       if oldValue == nil || !newValue.isEqual(oldValue) { 
        return true 
       } 
      } else if oldValue != nil { 
       return true 
      } 
     } 
    } 
    return false 
} 
関連する問題