连接Realm和SwiftBond的最佳方式是什么?

时间:2015-03-19 21:43:31

标签: ios swift architecture realm swiftbond

我爱Realm,我爱Bond。它们都使应用程序创建成为一种乐趣。所以我想知道连接Realm和Bond的最佳方式是什么?
在Realm中,我们可以存储基本类型,例如IntString,例如但在邦德,我们与DynamicBond合作。我发现连接Realm和Bond的唯一方法是:

class TestObject: RLMObject {

   dynamic var rlmTitle: String = ""
   dynamic var rlmSubtitle: String = ""

   var title: Dynamic<String>
   var subtitle: Dynamic<String>

   private let titleBond: Bond<String>!
   private let subtitleBond: Bond<String>!

   init(title: String, subtitle: String) {
      self.title = Dynamic<String>(title)
      self.subtitle = Dynamic<String>(subtitle)

      super.init()

      self.titleBond = Bond<String>() { [unowned self] title in self.rlmTitle = title }
      self.subtitleBond = Bond<String>() { [unowned self] subtitle in self.rlmSubtitle = subtitle }

      self.title ->> titleBond
      self.subtitle ->> subtitleBond
   }
}

但它肯定缺乏简洁和优雅,并产生大量的锅炉代码。有没有办法做得更好?

3 个答案:

答案 0 :(得分:6)

Realm支持KVO和Bond 4,您可以扩展Realm对象以提供Observable变体。它有一些样板,但它干净而没有黑客。

class Dog: Object {
  dynamic var name = ""
  dynamic var birthdate = NSDate(timeIntervalSince1970: 1)
}

extension Dog {

  class ObservableDog {
    let name: Observable<String>
    let birthdate: Observable<NSDate>

    init(dog: Dog) {
      name = Observable(object: dog, keyPath: "name")
      birthdate = Observable(object: dog, keyPath: "birthdate")
    }
  }

  func observableVariant() -> Dog.ObservableDog {
    return ObservableDog(dog: self)
  }
}

比你能做的更多:

let myDog = Dog().observableVariant()

myDog.name.observe { newName in
  print(newName)
}

myDog.name.bindTo(nameLabel.bnd_text)

realm.write {
  myDog.name.value = "Jim"
}

答案 1 :(得分:1)

如果使用的话,你可能会简化你正在使用的模式 默认属性值:

  class TestObject: RLMObject {

     dynamic var rlmTitle = ""
     dynamic var rlmSubtitle = ""

     var title: Dynamic<String>
     var subtitle: Dynamic<String>

     private let titleBond = Bond<String>() { [unowned self] title in self.rlmTitle = title }
     private let subtitleBond = Bond<String>() { [unowned self] subtitle in self.rlmSubtitle = subtitle }

     init(title: String, subtitle: String) {
        self.title = Dynamic<String>(title)
        self.subtitle = Dynamic<String>(subtitle)
        self.title ->> titleBond
        self.subtitle ->> subtitleBond

        super.init()
     }
  }

如果Bond的->>运算符返回,则可以删除另外两行代码 左值,这样你就可以self.title = Dynamic<String>(title) ->> titleBond

但最终,在Swift对KVO或同等观察机制提供本地语言支持之前,你很遗憾不得不写一些样板文件。

答案 2 :(得分:1)

我已经考虑了这三天了,并提出了几乎完美的解决方案,它不使用任何样板代码。首先,我为领域模型的包装器创建了一个超类:

class BondRealmBaseClass {

   private var realmModel: RLMObject!
   private let realm = RLMRealm.defaultRealm()
   private var bonds = NSMutableArray()

   init(){
      realmModel = createRealmModel()
      realm.beginWriteTransaction()
      realm.addObject(realmModel)
      realm.commitWriteTransaction()
      createBonds()
   }

   init(realmModel: RLMObject){
      self.realmModel = realmModel
      createBonds()
   }

   func createBondFrom<T>(from: Dynamic<T>, toModelKeyPath keyPath: String){
      from.value = realmModel.valueForKeyPath(keyPath) as T
      let bond = Bond<T>() { [unowned self] value in
         self.realm.beginWriteTransaction()
         self.realmModel.setValue(value as NSObject, forKey: keyPath)
         self.realm.commitWriteTransaction()
      }
      from ->| bond
      bonds.addObject(bond)
   }

   //MARK: - Should be overriden by super classes
   func createBonds(){ fatalError("should be implemented in supreclass") }
   func createRealmModel() -> RLMObject{ fatalError("should be implemented in supreclass") }
}

在每个领域模型之后,我创建两个类,首先是实际领域模型,它存储所有属性:

class RealmTodoModel: RLMObject { 
   dynamic var title = ""
   dynamic var date = NSDate()
}

,第二个是围绕领域模型的包装器:

class TodoModel : BondRealmBaseClass{
   let title = Dynamic("")
   let date = Dynamic(NSDate())

   override func createBonds(){
      createBondFrom(title, toModelKeyPath: "title")
      createBondFrom(date, toModelKeyPath: "date")
   }

   override func createRealmModel() -> RLMObject { return RealmTodoModel() }
}

这两个类实际上只需要链接RealmBond:创建新TodoModel实际上会添加到Realm新RealmTodoModel以及使用{进行的所有更改{1}} TodoModeltitle将自动保存到相应的date模型中!

修改

我添加了一些功能并将其作为GitHub上的框架发布。这是link