Skip to content
This repository was archived by the owner on Mar 27, 2026. It is now read-only.
This repository was archived by the owner on Mar 27, 2026. It is now read-only.

a simple example and some questions #10

Description

@mycroftcanner

I tried implementing a super simple example to get started:

struct SmokeStatus: Codable {
  let isEnabled: Bool
}

enum SmokeMessage {
  case smokeIsEnabled(_ flag: Bool)
}

typealias SmokeMessageHandler = MessageHandler<SmokeEnvironment, ApplicationModel.Smoke, SmokeMessage>

private let smokeIsEnabled: SmokeMessageHandler = .reducer { state, message in
  guard
    case let .smokeIsEnabled(flag) = message
  else { return }

  state.isEnabled = flag
}

let smokeMessageHandler = smokeIsEnabled

typealias SmokeCommand = Command<SmokeEnvironment, SmokeMessage>

enum SmokeCommands {
  static let isEnabled = { (flag: Bool) -> SmokeCommand in
    SmokeCommand { environment, publish in
      publish(SmokeMessage.smokeIsEnabled(flag))
    }
  }
}

typealias SmokeEnvironment = SmokeServiceContainer

struct ApplicationModel: Codable {
  enum CodingKeys: String, CodingKey {
    case smoke
  }

  struct Smoke: Codable {
    enum CodingKeys: String, CodingKey {
      case isEnabled
    }
    var isEnabled: Bool = true
  }
}

This is my view

struct SmokeViewBody: View {
  var model: SmokeView.ViewModel

  var body: some View {
    Form {
      Section() {
        Toggle(isOn: model.isEnabled) {
          Text("Notification:")
        }
      }
    }
    .navigationBarTitle("Quote of the day")
  }
}

struct SmokeView: View {
  struct ViewModel {
    var isEnabled: Binding<Bool>

    private let dispatcher: ApplicationStore.Dispatcher

    init(smoke: ApplicationModel.Smoke, dispatcher: ApplicationStore.Dispatcher) {
      self.dispatcher = dispatcher

      self.isEnabled = Binding<Bool>(get: { () -> Bool in
        smoke.isEnabled
      }) { newValue in
        dispatcher.send(SmokeCommands.isEnabled(newValue))
      }
    }
  }

  var body: some View {
    ApplicationStateContainer(\.smoke) { smoke, dispatcher in
      SmokeViewBody(model: ViewModel(smoke: smoke, dispatcher: dispatcher))
    }
  }
}

It works 👍

2019-09-30 21:41:06.372950+0200 Rework[17769:1105701] smokeIsEnabled(true)
2019-09-30 21:41:08.522575+0200 Rework[17769:1105283] smokeIsEnabled(false)

My questions:

  1. is this the right way to bind a simple value like a flag
  2. Why is it so laggy? It takes a second for the toggle to be updated.
  3. Should I use a @State so that the toggle is updated right away? Wouldn’t that defeat the purpose?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions