Tricertops / Objective-Chain

Object-oriented reactive framework, inspired by ReactiveCocoa
MIT License
236 stars 19 forks source link

Objective-Chain Flattr this

Object-oriented reactive framework written in Objective-C, that abstracts production, transformation and consumption of values in a declarative way.

Project is inspired by ReactiveCocoa, but takes more object-oriented approach.

Aim is to build reusable and scalable solution for MVVM bindings. Article about MVVM implementation using Objective-Chain.

Project can be reliably used in production. Follow the Roadmap for progress.

Concept

Everything happens for a reason and this is especially true in software. Basic principle of software is to receive input and provide output. Reacting to events with actions, but our actions can trigger new events. A reactive framework should allow you to write the rules declaratively. This means you write it once and it works forever (or at least until cancelled).

In iOS and OS X applications, we know multiple way to react on events: Target + Action, Notifications, Key-Value Observing, Delegation and Blocks. All of them have different characteristics and therefore they are used in different cases and using different APIs. Objective-Chain attempts to unify these callback mechanisms and allows you to easily receive events, filter or transform their values and subsequently execute actions or chain them to other events.

Event vs. Value

To avoid confusion, we should clarify the difference between Event and Value. The difference, for purpose of Objective-Chain, is none. Producing a Value is an Event and Events usually have some Value associated with them. And if not, No Value is still a Value.

Main Components

Core concept is really simple: Producers send values and Consumers receive them. Producer and Consumer are abstract terms, so the true functionality is provied by their concrete implementations.

Producers

Consumers

These were only the endpoints of Chain, now the fun begins…

Mediators

Mediator is simply a Producer and Consumer that can stand in between and make changes to the values. It never produces new values and never uses them in a meaningful way.

Creating Chains

You can use any of those provided components or create your own and chain them together to build the logic of your application. Examples:

  1. Listen for notification and invoke a selector:

    [[OCANotificator notify:NSUserDefaultsDidChangeNotification]
     connectTo:OCAInvocation(self, reloadPreferences)];
    • +notify: – Creates a Producer that listens for given notification.
    • OCAInvocation – Macro that creates NSInvocation for [self reloadPreferences] call.
    • -invoke: – Internally creates a Consumer OCAInvoker with given invocation and attaches it to the Notificator. Target of the invocation is stored weakly.
  2. Anytime the name of user changes, display it in a label:

    [OCAProperty(self, user.name, NSString)
     connectTo:OCAProperty(self, label.text, NSString)];
    • OCAPropertyMacro that creates an OCAProperty object. It takes a target, key-path and a class of values (NSString in both cases, more about class-validation later). Property object can act as both Producer and Consumer. This macro uses Xcode autocompletion and is validated during build time.
    • -connectTo: – Adds the argument to the receiver's list of Consumers. Any changes in user.name will be reflected by label.text.
  3. When text of text field doesn't change for 0.3 seconds, initiate search:

    [[[self.textField producerForText]
      throttle:0.3]
     connectTo:OCAInvocation(self, startSearchWithText: OCAPH(NSString) )];
    • -producerForText – Creates OCATarget Producer configured for the text field (receiver). Sends the entered text every time it changes.
    • -throttle: – Internally creates OCAThrottle Mediator with given delay, attaches it to the receiver and returns it (so we can continue chaining). Throttle will send the entered text only after it didn't change (nothing is received) for 0.3 seconds.
    • (-invoke: and OCAInvocation are described in the first example above)
    • OCAPH – Macro that is a short alias for OCAPlaceholder. When used as an argument of invocation passed to OCAInvoker, it will be replaced by real value. In this case, we used only one Placeholer, so the received text from text field (and throttled) will be passed to the invocation. Argument of the macro is class used for validation.

Example Project

For more code examples see included Chain Examples project. You can use it as a sandbox for experimenting with Objective-Chain and even submit a Pull Request, so your experiments will be merged into the master repo.

Additional Features

To be described later:

Follow the Roadmap for progress.


Check it, load it, link it, use it,
View it, code it, quick - combine it.

Chain it, branch it, merge it, fork it,
Switch it, send it, bridge - transform it.

Catch it, change it, call it, tune it,
Drag and drop it, box - unbox it.


Licensed under The MIT License (MIT)
Copyright © 2014-2015 Martin Kiss