Giter VIP home page Giter VIP logo

avalon's Introduction

#Avalon - MVVM for iOS

This project is currently a work-in-progress, and something I hope will grow into a fully-fledged MVVM framework for iOS Developers.

Why MVVM? and why Avalon?

In short, because I think it is the best pattern for any UI development! The pattern itself is quite simple, you place your logic within view models, then rely on a framework to wire-up the view model and your UI controls, keeping the two synchronised. That is the purpose of Avalon, it is the layer of glue between your view models and you view.

OK, show me some code!

As I mentioned, this is a work-in-progress and is not documented. If you want to see Avalon in action, the best place to start is the Examples folder:

  • ColorPicker - a really simple app that highlights how Avalon synchronises the view model and view state. Take a look at the various UI controls within the storyboard, the Attributes Inspector reveals how they are bound to the view.
  • SwiftWeather - a pretty, yet simple, app (courtesy of Jake Lin) modified to use Avalon. Note, this uses Cocoapods.
  • SwiftPlaces - a more complex app (courtesy of Josh Smith) modified to use Avalon. Shows things like table view binding. This app also shows that view models expose more than just state (i.e. properties), sometimes you need to use events. This concept is something I only recently introduced.
  • KitchenSink - have a guess? ;-)

avalon's People

Contributors

colineberhardt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

avalon's Issues

Replace ValueConverter with NSValueTransformer?

One advantage is that it already has a registry concept built-in ..

  • Change code to use NSValueTransformer
  • revisit naming of converters
  • Look at simplifying the implementation of transformers
  • Unit test the transformer name look-up
  • Determine whether the customer operators can be made to use the registry

Fix the KVO implementation

"ViewModelBase isn't doing KVO properly, you need to use a context parameter to ensure superclasses get called properly. It's not an issue given the current class hierarchy, but you're better off doing it the right way now instead of debugging it later, should the superclass change in the future. http://stackoverflow.com/a/11917449"

Add custom binding operators

Consider using custom operator functions to streamline Binding creation:

infix operator >| {}   // One-way binding
infix operator |<>| {} // Two-way binding

func >| (source: String, destination: String) -> Binding
{
    return Binding(source: source, destination: destination, mode: .OneWay)
}

func |<>| (source: String, destination: String) -> Binding
{
    return Binding(source: source, destination: destination, mode: .TwoWay)
}


    // bind the controls to the view model
//    searchBar.bindings = [Binding(source: "searchText", destination: "text", mode: .TwoWay),
//      Binding(source: "searchAction", destination: "searchAction")]
//
//    tableView.bindings = [Binding(source: "places", destination: "items"),
//      Binding(source: "placeSelectedAction", destination: "selectionAction")]

    searchBar.bindings = [
        "searchText" |<>| "text",
        "searchAction" >| "searchAction"
    ]

    tableView.bindings = [
        "places" >| "items",
        "placeSelectedAction" >| "selectionAction"
    ]

I neat idea via @ijoshsmith

Objective-C friction points

Because Avalon makes use of a number of Objective-C APIs (e.g. KVO, associated properties) it imposes a number of uncomfortable constraints. It would be great to be able to remove these at some point. Hopefully as the Swift language evolves, this will become possible!

  • View models must extend NSObject because they are stored in an associated property via the bindingContext
  • The ObservabeArray has to be a class, rather than a struct, because it is stored in associated properties. Swift structs cannot be bridged to Objective-C
  • Numerous types are marked @objc in order that they can be used as associated properties (probably worth a review to check this is necessary in all cases)

Guard against a delegateMultiplexer becoming its own delegate

Due to the implementation of the overridden didMoveToWindow: method, it's currently possible for a delegateMultiplexer to be set as its own delegate. This in turn causes an infinite loop, and stack overflow.

There's a partial hotfix in: sammyd@a6bbd3a

if delegate !== delegateMultiplexer {
  delegateMultiplexer.delegate = delegate
  self.delegate = delegateMultiplexer
}

I think there are other code paths that could cause the same effect - maybe it would make sense for the multiplexer to reject a delegate value of itself?

Table view cell image binding

Need to work out how this will be achieved, e.g. how to create a placeholder while images are loaded? what happens when cells are recycled?

Race condition in UISegmentedControl binding

If you bind the selected index first, then the items, the initial selection state is incorrect:

segmentedControl.bindings = [Binding(source: "selectedOption", destination: "selectedSegmentIndex", mode: .TwoWay), 
   Binding(source: "options", destination: "segments")]

Need to cache the value.

Support all UI controls with basic binding

Provide binding support to the following:

UIView subclasses

  • UILabel
  • UIPickerView
  • UIProgressView
  • UIActivityIndicator
  • UIImageView
  • UITabBar
  • UIToolbar
  • UICollectionView
  • UINavigationBar
  • UITableViewCell
  • UIActionSheet
  • UIAlertView
  • UIScrollView
  • UITableView
  • UITextView
  • UISearchBar
  • UIWebView

UIControl subclasses

  • UIButton
  • UIDatePicker
  • UIPageControl
  • UISegmentedControl
  • UITextField
  • UISlider
  • UISwitch

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.