Coder Social home page Coder Social logo

Comments (14)

stefanomondino avatar stefanomondino commented on May 18, 2024 1

@ashfurrow should we close this? bindTo() should have taken care of this

from action.

ashfurrow avatar ashfurrow commented on May 18, 2024 1

Cool, thanks! And thanks again for adding it!

from action.

fpillet avatar fpillet commented on May 18, 2024

That's one of the reasons why I mostly use Action<SomeType, Void> instead -- and that's perfectly fine! I view CocoaAction as just a shortcut for the most common case but don't have an issue with using Action when more flexibility is needed.

from action.

justinswart avatar justinswart commented on May 18, 2024

Submitted a pull request: #30

from action.

ashfurrow avatar ashfurrow commented on May 18, 2024

Could we use protocols to be sneaky here? Like:

typealias CocoaAction = Action<ActionInput, ActionOutput>

And then define those two protocols as empty and users can conform with their own types? Not sure. There's no easy answer, but I think it's an important discussion to have.

from action.

justinswart avatar justinswart commented on May 18, 2024

Hmm of course Swift 3 is going to come along in a little while and then we will have generic typealiases negating all of these workarounds. We could also consider a generic type wrapped in an enum/struct for now (the usual trick) until Swift 3? I'm not a huge fan of these but could work, eg:

struct GenericAction<Y, R> {
  typealias T = CocoaAction<Y, R>
}

let action = GenericAction<Void, Observable<String>>.T()

from action.

ashfurrow avatar ashfurrow commented on May 18, 2024

The problem comes from the rx_action property which, last time I tried, caused a compiler error in the UIButton extension.

from action.

stefanomondino avatar stefanomondino commented on May 18, 2024

It may sound stupid but.. why a CocoaAction has to be an Action?
In ReactiveCocoa they've implemented it as a standalone NSObject that can be assigned to UIControls (or its macOS equivalent, I'm not a Mac expert at all).
Basically it ties itself up to an existing Action and just provides a custom input parameter defined inside a closure whenever there's interaction with the control
I think it should be better to avoid useless creation of Actions (they involve too many observables in the process, it can be performance killer sometimes) if we only need a different input to perform the same thing.

from action.

stefanomondino avatar stefanomondino commented on May 18, 2024

I've tried to implement it (heavily "inspired" by RAC's CocoaAction) here
I've named it "ControlAction" so that it doesn't break current behaviour

The main drawback is that we're losing "Sender" type inside the closure, honestly I've never used it anyway.

from action.

ashfurrow avatar ashfurrow commented on May 18, 2024

Ah interesting, so it acts as like a wrapper for Action then? Neat idea. Anyone have feedback on this? Would love to discuss on a pull request.

from action.

ishkawa avatar ishkawa commented on May 18, 2024

I'm not sure that introducing Action wrapper is a right way for RxCocoa users.

I think our Action do not necessarily have to be the same as RAC's Action, because API design of each libraries differ from each other. RAC assumes that all actions triggered by Cocoa components is expressed as CocoaAction, but RxCocoa doesn't.

Additionally, we already have a mechanism that just provides a custom input parameter on Action.
inputs subject can receive flexible inputs like below:

let button = UIButton()
let barButtonItem = UIBarButtonItem()
let disposeBag = DisposeBag()

let action = Action<String, Void> { input in
    print("\(input) is pressed.")
}

button.rx.tap
    .map { _ in "UIButton" }
    .bindTo(action.input)
    .addDisposableTo(disposeBag)

barButtonItem.rx.tap
    .map { _ in "UIBarButtonItem" }
    .bindTo(action.input)
    .addDisposableTo(disposeBag)

Now, we have 2 choices to give a custom input parameters on Action:

  1. Use existing RxCocoa API and connect it to inputs subject.
  2. Add an action property to Cocoa components and set CocoaAction there.

Personally, I think 1 is more reasonable than 2.

from action.

stefanomondino avatar stefanomondino commented on May 18, 2024

@ishkawa this is really interesting, the main problem I see is that, in this way, the button's enabled property is not in sync with the action executing state.

I don't think either it's absolutely necessary to "mirror" RAC behavior, (otherwise I'd continue to use that instead of Rx.). It's not perfect at all, it's difficult to explain to new developers and has some "complications" that I don't need.
But, on the other hand, I don't see any downside to simply add a second "rx_action2" (I've called controlAction in my fork) that automatically many controls with a single action, with input customizations. It would not break (I think) any of the existing behaviors.

Let me also clarify why I came to this kind of conclusion.
Usually, when I do MVVM on iOS, I prefer to keep a single Action for each viewController's viewModel. In this way I can keep error and "showLoader" handling in one single place, and I don't have to replicate binding code for each action that could lead to an error (or could show a progress bar for long time operations). What really discriminates what the Action should do is the Input I provide to it. And the input depends on which button is pressed.
In this way, I have no business logic at all in the VC, i just have to tell the ViewModel to execute the Action with a converted input (usually an enum with all the possible choices in a viewModel). That's why I needed something different from your typealiased CocoaAction.

Maybe I can work out something on your suggestions that doesn't involve the creation of a new class, I'll let you know. In the meanwhile, THANKS :)

from action.

ashfurrow avatar ashfurrow commented on May 18, 2024

Let's keep it open until we add documentation to the readme?

from action.

stefanomondino avatar stefanomondino commented on May 18, 2024

ok, I'm trying to do it right now BTW

from action.

Related Issues (20)

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.