antoninbiret / rxeureka Goto Github PK
View Code? Open in Web Editor NEWThis library is a small RxSwift wrapper around Eureka
License: MIT License
This library is a small RxSwift wrapper around Eureka
License: MIT License
I duplicated and updated on my side, but I think this repo in its place, with a few more controls, buttonrow selected etc.
Hi,
Trying to use Carthage to include your library it's pointing me this
Targ|feature/eureka_try⚡ ⇒ carthage update
*** Fetching RxEureka
*** Checking out RxEureka at "0.2.1"
*** xcodebuild output can be found in /var/folders/hr/pwfk8qcn2lz77z5bwjrzshmc0000gn/T/carthage-xcodebuild.hnhRaN.log
*** Skipped building RxEureka due to the error:
Dependency "RxEureka" has no shared framework schemes
If you believe this to be an error, please file an issue with the maintainers at https://github.com/antoninbiret/RxEureka/issues/new
Any ideas? Googling "Dependency "" has no shared framework schemes" didn't work for me.
Your library is very usefull in an Eureka environment. Unfortunately it seems to only support rows which do have String
as their value type. Because of this, I have just adopted your ideas and added support for more types in my code directly. Of course, this way of doing is not in the spirit of open source but I had to move fast ;)
That said, I'll happily provide a pull request with support for additional types as soon as I find some spare time. What I basically did is a Copy & Paste of your Reactive RowOf<String>
extension and changed the type to e.g. Double
like this:
public var value: ControlProperty<Double?> {
var base: Base? = self.base
let source = Observable<Double?>.create { observer in
base?.onChange { row in
observer.onNext(row.value)
}
return Disposables.create {
base = nil
observer.onCompleted()
}
}
let bindingObserver = BindableObserver(container: self.base) { (row, value) in
row.value = value
}
return ControlProperty(values: source, valueSink: bindingObserver)
}
Of course Copy & Paste is not the best solution from an architectural point of view, but till now I was not able to come up with a better solution. Do you have any idea how we can solve this in a more generic way?
Hi, just to let you know that in the readme file you should maybe change the installation section with the following:
pod 'RxEureka', :git => 'https://github.com/antoninbiret/RxEureka'
instead of
pod "RxEureka", :git => '[email protected]/antoninbiret/RxEureka', :branch => 'master' (which doesn't seem to work, for me at least)
Cheers
Forgive my newly found ignorance with RxSwift, but after binding:
private func configureBindings() {
// Bind 'email' row to variable
self.emailRow!.rx.value
.asObservable()
.bind(to: self.viewModel.usernameText)
.disposed(by: self.disposeBag)
// Bind variable to 'email' row
self.viewModel.usernameText
.asObservable()
.bind(to: self.emailRow!.rx.value)
.disposed(by: self.disposeBag)
which has showed to respond when tested with:
self.viewModel.usernameText
.asObservable()
.subscribe(onNext: { value in
print("self.viewModel.usernameText did change to \(String(describing: value))")
})
.disposed(by: self.disposeBag)
A simple breakpoint and investigation into wanting to see proof that my self.viewModel.usernameText
value has indeed changed results in:
EXC_BAD_ACCESS
within the console.
Testing with the following doesn't update the cell with the new value.
self._configureBindings()
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0, execute: {
print("trigger")
self.model.text = Variable("testing...")
for row in self.form.rows {
row.updateCell()
}
})
(fyi: I changed your struct
to class
to perform this test)
When I press a ButtonRow I change the value of my binded viewmodel-form tuple. Although the updated is made, I can see the change through the form.values() method, the row is not automatically "re-displayed". I have to force it wether with row.reload() or selecting the row. Is this behaviour ok?
It's not clear to me why this happens.
When you init:
class ViewController: FormViewController {
let viewModel: ViewModeling = ViewModel(model: Model(text: "RxEureka", phone: "0000"))
...
within private func _configureBindings() {
when the order of binding sets up the Variable
first and then the row
:
self.model.text
.asObservable()
.bind(to: self._textRow.rx.value)
.disposed(by: self._disposeBag)
self._textRow.rx.value
.asObservable()
.bind(to: self.model.text)
.disposed(by: self._disposeBag)
The form field correctly displays the default value:
But when you swap the order, by binding the row
first and then the Variable
:
self._textRow.rx.value
.asObservable()
.bind(to: self.model.text)
.disposed(by: self._disposeBag)
self.model.text
.asObservable()
.bind(to: self._textRow.rx.value)
.disposed(by: self._disposeBag)
Even though I pod install & set Eureka to use swift 4.0
/GitHub/RxEureka/Example/Pods/Eureka/Source/Core/Section.swift:206:1: 'Collection' requires the types 'Section.SubSequence' (aka 'Array') and 'ArraySlice' be equivalent
/GitHub/RxEureka/Example/Pods/Eureka/Source/Core/Section.swift:232:1: Type 'Section' does not conform to protocol 'RangeReplaceableCollection'
/GitHub/RxEureka/Example/Pods/Eureka/Source/Core/Section.swift:206:1: Type 'Section' does not conform to protocol 'BidirectionalCollection'
I shall be very grateful if you could tell me how to compile successfully ,thank you.
Are there any plans in adding Carthage support for this library?
Thanks a lot for RxEureka.
Did you know a way to observe a MultiValuedSection changes? How can I extend RxSwift for do that?
It would be awesome to filter out value changes only after the user has finished editing. On the Eureka side this can be done by adding a onCellHighlightChanged
callback like follows:
row.onCellHighlightChanged { _, row in
guard false == row.isHighlighted, row.wasChanged else { return }
//the user has finished editing and the row was changed
}
However, this approach has one major flaw: This event may miss some changes as it is not fired for every row type. E.g. SwitchRow
does not change it's cell highlight state.
That said, we may simply add a new extension for isHighlighted
the developer can subscribe to. This extension looks very similar to the var value: ControlProperty<String?>
:
public var isHighlighted: ControlProperty<Bool> {
var base: Base? = self.base
let source = Observable<Bool>.create { observer in
observer.onNext(base?.isHighlighted ?? false)
base?.onCellHighlightChanged{ _, row in
observer.onNext(row.isHighlighted)
}
return Disposables.create {
base = nil
observer.onCompleted()
}
}
let bindingObserver = BindableObserver(container: self.base) { (row, value) in
row.isHighlighted = value
}
return ControlProperty(values: source, valueSink: bindingObserver)
}
With this in place, the developer can choose to use the following code in order to only receive the latest value after the user has finished editing (untested):
Observable.combineLatest(
row.rx.isHighlighted,
row.rx.value
){ (isHighlighted: $0, value: $1) }
.subscribe(onNext: { isHighlighted, value in
//`isHighlighted == false` indicates that the user did end editing
//`value` contains the latest value
}).dispose(by: disposeBag)
What's your thoughts?
Reentrancy anomaly was detected.
when trying to set the model value so it refreshes the view. i get this error. can you please tell me what the problem might be, thank you.
self.model.name.accept("test")
I was running into a memory leak adopting your Reactive extension which was quite huge, if it is adopted to the ImageRow
.
Basically the issue was, that self.base
was referenced directly and therefore was never released. That said, this code causes the leak (taken from here):
public var value: ControlProperty<String?> {
let source = Observable<String?>.create { observer in
observer.onNext(self.base.value)
self.base.onChange({ (row) in //<---- this `self.base` reference causes the leak
observer.onNext(row.value)
})
return Disposables.create {
observer.onCompleted()
}
}
let bindingObserver = BindableObserver(container: self.base) { (row, value) in
row.value = value
}
return ControlProperty(values: source, valueSink: bindingObserver)
}
We can resolve this by using a local Optional
which references base and is released on disposal:
public var value: ControlProperty<String?> {
let source = Observable<String?>.create { observer in
var base: Base? = self.base
observer.onNext(base?.value)
base?.onChange({ (row) in
observer.onNext(row.value)
})
return Disposables.create {
base = nil
observer.onCompleted()
}
}
let bindingObserver = BindableObserver(container: self.base) { (row, value) in
row.value = value
}
return ControlProperty(values: source, valueSink: bindingObserver)
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.