Code Monkey home page Code Monkey logo

combinefeedback's People

Contributors

fontno avatar heckj avatar mluisbrown avatar paulwoodiii avatar ruiaaperes avatar sergdort avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

combinefeedback's Issues

Programmatic Navigation for MacOS

Programmatic navigation has a dependency on NavigationView, but it has Safari-File-Picker behavior on MacOS which is not the most convenient one ๐ŸŒš. I tried to find workarounds for a while so maybe this will be helpful for other MacOS developers, which will use CombineFeedback ๐Ÿ™‚

  • Here is a draft for manual NavigationView implementation (no_animation).
  • Xcode 12 supports switch expressions, which can be handy for navigation, especially in MacOS, so I came to this solution

What is the best way for systems to communicate to each other.

There are example project, it showcase how to use stores independently and as a single store.
However in real life use case, usually one system need to communicate to each other:

for example:
We have an authentication_system and sign_in_system.
A persist_session_event in auth system will be triggered by signed_in_event from sign_in_system.

Can you share how to achieve that with the framework?

Documentation - I can help

I am having trouble to follow the framework when it comes to the Feedback context and although you can read the code, not sure how (some) feedbacks are connected to the event, it looks like there are various flavors of Feedback, some are invoked every time state change and some are not making it difficult to understand when to use what.

Example:

// Having the below ViewModel

final class ViewModel: CombineFeedbackUI.Store<HostBroadcast.State, HostBroadcast.Event> {
    
    init(initial: State = State()){
      super.init(
        initial: initial,
        feedbacks: [
          ViewModel.whenBroadcastFinished(),
          ViewModel.whenSomethingElseHappened()
        ],
        reducer: HostBroadcast.reducer
      )
    }
    
    static func whenSomethingElseHappened() -> Feedback<State, Event> {
      return Feedback.custom { state, consumer in
        print("whenSomethingElseHappened")
        return Empty().eraseToAnyPublisher().start()
      }
    }
    
    static func whenBroadcastFinished() -> Feedback<State, Event> {
      return Feedback(effects: { (state) -> AnyPublisher<Event, Never> in
        print("\(state.status)")
        guard state.status.isBroadcastFinished else {
          print("#Broadcast not finished...")
          return Empty().eraseToAnyPublisher()
        }
        print("#Broadcast finished...")
        return Empty().eraseToAnyPublisher()
      })
    }
    
  }

whenSomethingElseHappened feedback will execute when the whole view is redrawn by the system; in my case every time a tab item selected change, but not when a button action in the view or onAppear emits an event Button(action: context.action(for: .didFinishBroadcast)), .onAppear { self.context.send(event: .shouldConnect) }

I'd appreciate it if I can further read somewhere how the Feedback lifecycle or connection to the events raised is working. I can also help with documentation.

Discrepancy in the Examples

In the lib itself, the Reducer<State, Event> is a typealias, like so:
public typealias Reducer<State, Event> = (inout State, Event) -> Void
In the Examples however, they use a struct, with an init, like so:

` public let reduce: (inout State, Event) -> Void

public init(reduce: @escaping (inout State, Event) -> Void) {
    self.reduce = reduce
} etc...`

Where is the truth? :)

Thanks for the work on the library!

Is Builder intended to be included in the library?

Following the examples in my own project, I realized that the Builder helper protocol is not part of the library. Is that an oversight or should I just copy the set method directly in my own project?

Example how to integrate in my project avoiding copy-paste

Trying to figure out if this is installed as a git submodule, clone and copy the files (I'm sure not), any help appreciated, a newbie in Swift and I'd expect something like cocoapods. Any keywords for me to Google is appreciated too :)

Duplicate declarations of feedback static methods in examples

I noticed that the the when_() -> Feedback<State, Event> static methods are defined both in the viewModel and in the corresponding enum in the examples. It's not necessary given that the view model can just access them from the enum type, ex:

...
feedback: [MoviesList.whenLoading()],
...

Can you please confirm that the current duplication is not the intended way?

How to pass additional @Binding parameters to the View from another parent View

I have a parent View with a TabView and a custom modifier to present a custom full modal view (doesn't exist in SwiftUI so custom work had to be done)

struct ContentView: View {
  
  @ObservedObject private var tabData = MainTabBarData(initialIndex: 1, customItemIndex: 3)
  
  var body: some View {
    
    TabView(selection: $tabData.itemSelected){
      // tab items with views and tags
    }
    .present($tabData.isCustomItemSelected, // Present the modal view when isCustomItemSelected @State is true
             view: Widget(store: HostBroadcast.ViewModel(), content: BroadcastLiveView.init), // Using CombineFeedbackUI Widget passing the viewmodel and content view
// I need somehow to link the isPresented: $tabData.isCustomItemSelected so that I can toggle it from the BroadcastLiveView to close the modal, or if feasible signal from HostBroadcast.ViewModel the state change to MainTabBarData
             style: .fade)

My BroadcastLiveView.init is following 0.7.0 tag source code examples.

  typealias State = HostBroadcast.State
  typealias Event = HostBroadcast.Event
  
  @ObservedObject
  var context: Context<State, Event>
  
  init(context: Context<State, Event>) {
    self.context = context
    logInit(of: self)
  }

I'd love to understand if this somehow can happen in ViewModel context, I have a Feedback where I check if the button to close the view tapped but I lack understanding how to tell the MainTabBarData ObservableObject that isCustomItemSelected should be false.

Type 'Reducer<HostBroadcast.State, HostBroadcast.Event>' (aka '(inout HostBroadcast.State, HostBroadcast.Event) -> ()') has no member 'init'

I am following the SignIn example and I get the error in the static func reducer() -> Reducer<State, Event> method.

Type 'Reducer<HostBroadcast.State, HostBroadcast.Event>' (aka '(inout HostBroadcast.State, HostBroadcast.Event) -> ()') has no member 'init'

Screen Shot 2020-06-25 at 07 27 50

Below is my HostBroadcastState.swift implementation.

import Foundation
import CombineFeedback
import Combine

enum HostBroadcast {
  
  struct State: Equatable {
    var status = Status.idle
    
    var error: NSError? {
      switch status {
        case .failed(let error):
          return error
        default:
          return nil
      }
    }
    
    enum Status: Equatable {
      case idle
      case connecting
      case connected
      case broadcasting
      case failed(NSError)
    }
  }
  
  enum Event {
    case willConnect
    case didConnect
    case didFail(NSError)
    case retry
  }
  
  static func reducer() -> Reducer<State, Event> {
    .init { state, event in  // ERROR HERE
      switch event {
        case .willConnect:
          state.status = .connecting
        case .didFail(let error):
          state.status = .failed(error)
        case .retry:
          state.status = .connecting
        case .didConnect:
          state.status = .connected
      }
    }
  }
  
}

And my HostBroadcastViewModel.swift

import Foundation
import Combine
import CombineFeedback
import CombineFeedbackUI

extension HostBroadcast {
  final class HostBroadcastViewModel: Store<HostBroadcast.State, HostBroadcast.Event> {
    
    init(initial: State = State()){
      super.init(
        initial: initial,
        feedbacks: [
          
        ],
        reducer: HostBroadcast.reducer()
      )
    }
    
  }
}

Help is appreciated, thank you for the amazing work. Big fan!

multi screens

Hi
I am trying use this nice framework , but I am struggling in problem how to manage state in multi screens application , can you provide a simple example of application with some screens , and in example with signIn :

static var feedback: Feedback<State, Event> {
return Feedback.combine(
whenChangingUserName(api: GithubAPI()),
whenSubmitting(api: GithubAPI())
)
}
why need it ?
Thanks in advance.

Add `@_exported import Combine`

I think it would be convenient to export Combine to avoid duplicated import like so

import Combine
import CombineFeedback

(The first one seems redundant for me)

And @_exported import SwiftUI for CombineFeedbackUI

[Question] ViewModels notified about state change outside of a view

Hey, this is a really interesting library, simple and nice to use, but I'm having hard times trying to figure out how to share data between multiple views.

What is the best approach to communicate state change and get feedbacks outside of a View/ViewModel?

Should it be done subscribing to the state: AnyPublisher<State, Never> property of the view model? Or sending a Feedback to the view model?

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.