# Bindings
**Repository Path**: mirrors_thoughtbot/Bindings
## Basic Information
- **Project Name**: Bindings
- **Description**: Unidirectional binding operators for Combine
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2020-08-18
- **Last Updated**: 2026-01-03
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# _Bindings_ for Combine
Unidirectional binding operators and reactive extensions for Cocoa
classes.
## The operators
*Bindings* provides two operators: `<~`, the **input binding operator**, and
`~>`, the **output binding operator**.
### Input bindings update the state of your UI
```swift
import Bindings
import UIKitBindings
nameLabel.reactive.text <~ viewModel.fullName
```
### Output bindings respond to changes
```swift
nameField.reactive.edited ~> viewModel.setName
UIApplication.reactive.didBecomeActiveNotification ~> viewModel.refresh
```
## Common bindings for system classes
In addition to the core operator definitions, _Bindings_ also provides
conveniences for using bindings with many system classes. Take a look at the
following modules to see what's provided (and consider
[contributing][CONTRIBUTING]!):
- [`UIKitBindings`][uikit] for apps using UIKit (iOS, iPadOS, Catalyst and more)
- More to come...
[uikit]: /Sources/UIKitBindings
## Reactive extensions
It's convenient to group reactive extensions into their own namespace,
especially when extending types you don't own with reactive APIs.
Use the `ReactiveExtensionProvider` protocol to define the `.reactive` property
on your types:
```swift
extension MyViewModel: ReactiveExtensionProvider {}
```
Then add reactive extensions via the `Reactive` type:
```swift
extension UserDefaults {
var username: String? {
get { string(forKey: "username") }
set { set(newValue, forKey: "username") }
}
}
extension Reactive where Base: UserDefaults {
var username: NSObject.KeyValueObservingPublisher {
base.publisher(for: \.username)
}
}
UserDefaults.standard.reactive.username.sink { username in
print("New username: \(username)")
}
```
## Bindings last for the lifetime of their owner
In Combine, the `AnyCancellable` class controls the lifetime of a subscription.
Subscriptions can be automatically cancelled by using the `store(in:)` method:
```swift
import UIKit
class MyViewController: UIViewController {
@IBOutlet private var usernameLabel: UILabel!
private var subscriptions: [AnyCancellable] = []
override func viewDidLoad() {
super.viewDidLoad()
UserDefaults.standard.reactive.username
.sink { [usernameLabel] in usernameLabel?.text = $0 }
.store(in: &subscriptions)
}
}
```
_Bindings_ encapsulates this pattern with the `BindingOwner` protocol, which
automatically defines a `subscriptions` collection on all conforming classes.
The `BindingSink` subscriber then automatically disposes of the binding
subscription when its `owner` goes out of scope:
```swift
extension Reactive where Base: UILabel {
var text: BindingSink {
BindingSink(owner: base) { label, newValue in
label.text = newValue
}
}
}
// automatically cancelled when `usernameLabel` goes out of scope
usernameLabel.reactive.text <~ UserDefaults.standard.reactive.username
```
## Contributing
Have a useful reactive extension in your project?
Please consider contributing it back to the community!
For more details, see the [CONTRIBUTING][] document.
Thank you, [contributors][]!
[CONTRIBUTING]: CONTRIBUTING.md
[contributors]: https://github.com/thoughtbot/Bindings/graphs/contributors
## License
Bindings is Copyright (c) 2019 thoughtbot, inc.
It is free software, and may be redistributed
under the terms specified in the [LICENSE][] file.
[LICENSE]: /LICENSE
## About

Bindings is maintained and funded by thoughtbot, inc.
The names and logos for thoughtbot are trademarks of thoughtbot, inc.
We love open source software!
See [our other projects][community]
or [hire us][hire] to help build your product.
[community]: https://thoughtbot.com/community?utm_source=github
[hire]: https://thoughtbot.com/hire-us?utm_source=github