Bond

A Swift binding framework

MIT License

Stars
4.2K
Committers
86

Bot releases are hidden (Show)

Bond - 7.3.2

Published by srdanrasic over 5 years ago

  • Fix compilation with Swift 5 (Xcode 10.2). Thanks @jonathanfoster!
Bond - 7.3.1

Published by srdanrasic over 5 years ago

  • Make Array2D.Section initializer public.
Bond - 7.3.0

Published by srdanrasic over 5 years ago

Bond v7.3 improves ergonomics around Tree types.

Simpler conformance

Trees no long need to be index-based. Conforming to TreeProtocol (renamed from TreeNodeProtocol) now requires only that the children property is provided.

/// A protocol that provides abstraction over a tree type.
/// A tree can be any containter type that encapsulates objects or values that are also trees.
public protocol TreeProtocol {

    /// A collection of child nodes that are trees and whose children are also trees
    associatedtype Children: Collection where
        Children.Element: TreeProtocol,
        Children.Element.Children == Children,
        Children.Index == Int

    /// Child nodes of the current tree node.
    var children: Children { get }
}

Not that you'll ever need to conform UIView, bet let's use it as an example:

extension UIView: TreeProtocol {

    public var children: [UIView] {
        return subviews
    }
}

This will automatically provide you index path subscripting capability:

let pickerView = UIPickerView()

let secondSubviewOfFirstSubview = pickerView[childAt: [0, 1]]

Tree Views

Consuming trees is now done through "tree views". Bond provides two views out of the box: DFS and BFS views thorough .depthFirst and .breadthFirst properties on any TreeProtocol.

For example, the snippet

for descendent in pickerView. depthFirst {
    print(descendent)
}

will print all descendent views of the pickerView in depth-first search order. Note that descendent implies not only children, but also children of the children and so on.

Tree view is a flat collection of tree nodes. It's of type Collection whose indices are of type IndexPath. That means that we can do all the stuff on trees that we can do with collections, like:

let firstImageViewDescendent = pickerView.breadthFirst.first(where: { $0 is UIImageView })

let allVisible = pickerView.breadthFirst.allSatisfy { !$0.isHidden }

let totalWidth = pickerView.breadthFirst.reduce(0, { $0 + $1.frame.size.width })

Mutable Trees

To add support for various mutating methods on the tree, conform to RangeReplaceableTreeProtocol protocol. All that is needed is to add setter to children property:

extension UIView: RangeReplaceableTreeProtocol {

    public var children: [UIView] {
        get {
            return subviews
        }
        set {
            subviews.forEach { $0.removeFromSuperview() }
            newValue.forEach { addSubview($0) }
        }
    }
}

We can then do stuff like inserting, deleting or moving children:

// Moves child at index path [0, 1] to index path [2, 3]
pickerView.move(from: IndexPath(indexes: [0, 1]), to: IndexPath(indexes: [2, 3]))

(Mutable) Observable Trees

Now that our tree type conforms to TreeProtocol (or RangeReplaceableTreeProtocol) we can wrap it onto MutableObservableTree and use the wrapper to enable observation of the tree changes:

let tree = MutableObservableTree(pickerView)

tree.observeNext { changeset in
    print(changeset.collection, changeset.diff, changeset.patch)
}

tree.insert(UIImageView(), at: [0, 0])

Simpler Array2D

Array2D is refactored into a simple struct. Changes should be backward compatible if Array2D typealias has been used.

public struct Array2D<SectionMetadata, Item>: Array2DProtocol {

    /// Represents a single section of Array2D.
    public struct Section {

        /// Section metadata, e.g. section title.
        public var metadata: SectionMetadata

        /// Items contained in the section.
        public var items: [Item]
    }

    /// All sections of Array2D.
    public var sections: [Section]

    /// Create a new Array2D with the given sections.
    public init(sections: [Section] = []) {
        self.sections = sections
    }
}
Bond - 7.2.1

Published by srdanrasic over 5 years ago

  • Support for Swift 5 compiler (in Swift 4.2 compatibility mode).

Note that this does not update the project to use Swift 5 syntax, it only makes the project compilable with Swift 5 compiler by reworking parts that are affected by Swift 5 breaking changes. You can keep using Swift 4.2 (Xcode 10/10.1).

Bond - 7.2.0

Published by srdanrasic over 5 years ago

  • Add firstIndex method to trees (#587)
  • Fix broken removeAllItems method on trees / 2D arrays (#584)
  • Add support for binding of collection signals to changeset containers like MutableObservableArray (#580)
  • Add data source binding extensions to UIPickerView - thanks @jonathanfoster! (#577)
Bond - 7.1.0

Published by srdanrasic over 5 years ago

  • Support for Tree diffing. Also implies Array2D diffing.

You can now calculate diffs between trees. For example, a mutable tree can be updated like this:

aMutableTree.replace(with: newTree, performDiff: true)
Bond - 7.0.0

Published by srdanrasic almost 6 years ago

Bond 7 brings refactored observable collections that are much more powerful and makes it easy to customize binders and create your own variants of observable collections. Anything that conforms to Swift.Collection can now be made observable. Bond supports observable trees now! Check out observable collections documentation, new playgrounds in the project workspace and the migration guide.

Bond 7 updates only observable collections APIs. All other APIs remain unchanged.

Bond - 7.0.0-beta.2

Published by srdanrasic almost 6 years ago

  • Expose convenience collection methods on immutable changeset container.
  • Add removeSubrange() method to mutable observable array.
  • Make UIButton image and backgroundImage bonds of optional type.
  • Make table and collection view properties of binder data source open.
Bond - 7.0.0-beta.1

Published by srdanrasic almost 6 years ago

Bond 7 brings refactored observable collections that are much more powerful and makes it easy to customize binders and create your own variants of observable collections. Anything that conforms to Swift.Collection can now be made observable. Bond also supports observable trees now! Check out observable collections documentation and new playgrounds in the project workspace.

Bond 7 updates only observable collections APIs. All other APIs remain unchanged. APIs for use cases like creating, mutating and binding collections remain mostly unchanged, however there are breaking changes in the collection binders and the observable collection event type. Make sure to check out playgrounds in the project workspace to learn about new stuff.

Bond - 6.10.2

Published by srdanrasic about 6 years ago

  • Fix submodules protocol (ssh -> https).
Bond - 6.10.1

Published by srdanrasic about 6 years ago

  • Update dependencies
Bond - 6.10.0

Published by srdanrasic about 6 years ago

  • Swift 4.2 support - thanks @maurovc!
Bond - 6.9.0

Published by srdanrasic about 6 years ago

  • Gesture recognizers for AppKit.
Bond - 6.8.3

Published by srdanrasic over 6 years ago

  • Disable code coverage in Release.
Bond - 6.8.2

Published by srdanrasic over 6 years ago

  • Fix macOS deployment target.
Bond - 6.8.1

Published by srdanrasic over 6 years ago

  • Property handle nil ObjC object instances in protocol proxies.
Bond - 6.8.0

Published by srdanrasic over 6 years ago

  • Update framework to Swift 4.1 (Xcode 9.3).

Warning: Stay on v6.7.x if you are not using Swift 4.1.

Bond - 6.7.1

Published by srdanrasic over 6 years ago

  • Allow subclassing table/collection view binders without providing a createCell closure in the constructor.
Bond - 6.7.0

Published by srdanrasic over 6 years ago

  • Clean up table and collection view bindings APIs.
  • TableViewBond protocol is now deprecated in favour of TableViewBinder class. Check out the updated documentation on table and collection view bindings.
  • Add UISearchBar text extension. Thanks @harryblam and @dantheli!
Bond - 6.6.1

Published by srdanrasic over 6 years ago

  • Replace ReferenceWritableKeyPath with KeyPath in observe method. Thanks @tonyarnold!
  • Fixed UICollectionView issues when performing partial updates while view is not yet displayed. Thanks @killev!