Skip to content

Instantly share code, notes, and snippets.

@kovs705
Last active December 23, 2023 10:13
Show Gist options
  • Save kovs705/34d1822e339bc74bacd2dffa77957c77 to your computer and use it in GitHub Desktop.
Save kovs705/34d1822e339bc74bacd2dffa77957c77 to your computer and use it in GitHub Desktop.
Combine function to observe parameters in @observableobject
// MARK: - Combine
/// Combine function to observe parameters in @ObservableObject
///
/// Example:
/// _ = newBindChangePublisher(for: <yourState object>, publisher: <yourStateObject>.$<parameter>.eraseToAnyPublisher(), keyPath: \.<parameter>, with: 0.4, handleAction: { [weak self] <nameOfParametersValue> in
/// guard let self = self else { return }
/// // perform action with the <nameOfParametersValue>
/// })
///
/// - Parameters:
/// - state: your @ObservableObject state
/// - publisher: @Published parameter in your state
/// - keyPath: source to the @Published parameter
/// - debounce: time between pushing new changes (0.4, 1 or 0 if you need to immediately push changes)
/// - handleAction: action with new value inside callback
/// - Returns: publisher for your ViewModel, that you place inside init()
func newBindChangePublisher<Publisher: Equatable, State: ObservableObject>(for state: <YourStateObject>, publisher: AnyPublisher<Publisher, Never>, keyPath: ReferenceWritableKeyPath<<YourStateObject>, Publisher>, with debounce: Double, handleAction: @escaping (Publisher) -> Void) -> AnyPublisher<T, Never> {
publisher
.receive(on: RunLoop.main)
.sink { value in
handleAction(value)
}
.store(in: &cancellables)
return state.objectWillChange
.compactMap { _ in
state[keyPath: keyPath] as? T
}
.debounce(for: RunLoop.SchedulerTimeType.Stride(debounce), scheduler: RunLoop.main)
.removeDuplicates()
.eraseToAnyPublisher()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment