Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RAC-3.0] Question 2-Way Binding Example? #1986

Closed
theladyjaye opened this issue May 8, 2015 · 8 comments
Closed

[RAC-3.0] Question 2-Way Binding Example? #1986

theladyjaye opened this issue May 8, 2015 · 8 comments
Labels

Comments

@theladyjaye
Copy link

I'm assuming 2 way binding is something like this?

@IBOutlet weak var myNSTextField //...assume it's assigned
var myModelWithMutableProperties // ... assume it's assigned


let inputProducer = myNSTextField.rac_textSignal().toSignalProducer()

myModelWithMutableProperties.someName.producer.start(next: {value in
    self.myNSTextField.stringValue = value
})

inputProducer.start(next: { value in
    myModelWithMutableProperties.someName.value = value as? String
})
@neilpa neilpa added the question label May 8, 2015
@neilpa
Copy link
Member

neilpa commented May 8, 2015

I would take a look at ReactiveCocoa/EditableProperty that @jspahrsummers recently started to enable multi-way binding.

@larryonoff
Copy link
Contributor

I assume that my code contains extra code, but I have implemented two-way binding for NSUserDefaults in the following way.

private let _property: MutableProperty<String>
var property: PropertyOf<String> {
    return PropertyOf(_property)
}
_property = MutableProperty<String>("")
_property <~ userDefaults.rac_signalForKey(SomeKey)

updatePropertyAction = Action<String, String, NoError> {
    userDefaults.setObject($0, forKey: UserDefaultsKeywordsKey)
    userDefaults.synchronize()

    return SignalProducer.empty
}

@theladyjaye
Copy link
Author

how does updatePropertyAction get used? I don't see the connecting piece of code that makes use of that Action. everything else makes sense in your example.

@larryonoff
Copy link
Contributor

The property and updatePropertyAction are implemented inside ViewModel. updatePropertyAction is triggered in ViewController. See

propertyTextView.rac_textSignal().toSignalProducer()
    |> ignoreError
    |> map { $0 as? String ?? "" }
    |> map { property in
        return self.viewModel.updatePropertyAction.apply(property) |> ignoreError
    }
    |> flatten(FlattenStrategy.Concat)
    |> start()

@larryonoff
Copy link
Contributor

It would be great if @jspahrsummers comments about the direction of my thoughts.

@jspahrsummers
Copy link
Member

@larryonoff Seems like that could cause a recursive notification if the thing observing the property is also the thing modifying user defaults.

@larryonoff
Copy link
Contributor

@jspahrsummers I agree. This is why NSUserDefaults.rex_signalForKey was written in neilpa/Rex repo. Now it shouldn't cause a recursive notification.

extension NSUserDefaults {
    /// Sends value of key when the value is changed
    func rex_signalForKey(key: String) -> Signal<AnyObject?, NoError> {
        let (signal, observer) = Signal<AnyObject?, NoError>.pipe()

        // send initial value
        let initial: AnyObject? = self.objectForKey(key)
        sendNext(observer, initial)

        // observe other values
        let defaultsDidChange = NSNotificationCenter.defaultCenter().rac_notifications(name: NSUserDefaultsDidChangeNotification, object: self)
        defaultsDidChange.observe(next: { notification in
            let value: AnyObject? = self.objectForKey(key)

            sendNext(observer, value)
        }, completed: {
            sendCompleted(observer)
        })

        return signal
            |> skipRepeats { a, b in
                    if let a = a as? NSObject, b = b as? NSObject where a.isEqual(b) {
                        return true
                    } else {
                        return false
                    }
            }
    }
}

@jspahrsummers
Copy link
Member

In any case, it looks like the question here has been answered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants