Skip to content

How does Beacon relate to other binding frameworks

Michael edited this page May 10, 2016 · 8 revisions

XAML

Beacon is pretty similar to XAML in that you can provide more or less the same functionality in binding expressions. Both Interface Builder/CocoaTouch and Visual Studio/WPF use XML to specify view hierarchies. XAML has integrated support for data binding. Binding expressions are defined as attributes of UI components. The DSL for binding expression in XAML and Beacon is different but has a similar scope. Beacon is more flexible and extendible, mainly because it has to be.

One thing that feels a lot better with beacon is that you don't have to implement change events manually in Objective-C or Swift, because KVO does most of the work for you (you still have to publish change events or dependencies in some situations like for example for computed properties)

Knockout

It's also not too different from Web-Binding frameworks like Knockout.

Knockout binding expressions are defined as data attributes on HTML elements. Knockout uses or integrates JavaScript in binding expressions which is rather powerful compared to both Beacon and WPF. Knockout uses observables for change propagation which serve a similar purpose to how AKAProperty instances are used, even though you rarely see them in Beacon.

Code based iOS binding frameworks

There are a couple of binding solutions for iOS which save you from having to implement KVO manually.

That's already a huge improvement, but I feel like it falls short of what a binding framework should do: reduce glue code or better eliminate it altogether and maybe even more import, promote a better application architecture. I also think that semantically binding specifications belong to the presentation (views) and not into code, simply because that enables the code to be more agnostic about pure presentation (and thus more flexible and likely to result in reusable code that is easier to understand).

It also feels rather redundant to have code fragments like:

@property(nonatomic, weak) IBOutlet UITextField firstNameTextField;
@property(nonatomic, weak) IBOutlet UIDatePicker birthDatePicker;
...

- (void)setupBindings {
  x_bind(self.firstName, self.firstNameTextField);
  x_bind(self.birthDate, self.birthDatePicker);
  ...
}

and then you still have to create outlets for all views that you want to connect. That is also a problem because you can't connect outlets for dynamic views like table view cell prototypes, so you need even more code and it's rather likely that your view controller will implement all kinds of delegates to wire up this code.

And of course, the view controller is completely tied to the specific presentation. It knows that is a UIDatePicker and a UITextField and whatever else you have in your view hierarchy and changing anything means that to have to change everything.

The advantage of such an imperative approach to data binding is that the control flow is transparent in code, you see who is doing what, while in beacon stuff just happens. The disadvantage in this advantage is however that you see who is doing stuff because you have to do it yourself, often, in a noisy way.

In Beacon, you have a textBinding property on labels and set it to firstName and that's about all what you have to do. And it works in any label that is part of the view hierarchy managed by beacon (if your table view uses a dataSourceBinding, then the cells, table view headers, section headers and footers can all use bindings without you having to do anything more than configure the binding expressions in your views. And the view model/view controller does not have to do any more than providing the data and enable binding support (one-liner).