4

我爱Realm,我爱Bond。它们都使应用程序创建成为一种乐趣。所以我想知道连接 Realm 和 Bond 的最佳方式是什么?
在 Realm 中,我们可以存储基本类型,例如Int, String, eg 但是在 Bond 中我们使用Dynamics 和Bonds。我发现连接 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
   }
}

但它确实缺乏简单性和优雅性,并且产生了大量的锅炉代码。有没有办法更好地做到这一点?

4

3 回答 3

6

借助支持 KVO 和 Bond 4 的 Realm,您可以扩展 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"
}
于 2015-08-30T14:36:00.400 回答
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 或等效的观察机制提供本地语言支持之前,您将不得不编写一些样板文件。

于 2015-03-20T23:47:46.553 回答
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:create newTodoModel实际上会添加到 Realm new 中,所有使用's所做的RealmTodoModel更改都会自动保存到相应的模型中!TodoModeltitledateRealm

编辑

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

于 2015-03-21T14:58:27.897 回答