Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/combine additions #54

Merged
merged 5 commits into from
Oct 21, 2020
Merged

Feat/combine additions #54

merged 5 commits into from
Oct 21, 2020

Conversation

stephanecopin
Copy link
Contributor

@stephanecopin stephanecopin commented Oct 14, 2020

Goals ⚽

This PRs add a substantial amount of Combine helper, and adds a CombineUIKit new subspec that aims to provide a similar level of helpers as ReactiveCocoa did.
A small summary of the changes (the following changes relates to Combine):

  • Fix a bug in Action where a cancellation would be ignored and not set isExecuting to false
  • Add ActionProtocol
  • Add AnyAction, allowing to type-erase any actions represented by a ActionProtocol
  • Add CoalescingAction & OverridingAction
  • Add a CombineExtensions & CombineExtensionsProvider protocol, replicating the .reactive of ReactiveSwift (so as not to pollute too much the global namespace)
  • All NSObject now can have a cancellables object attached to them via <object>.combineExtensions.cancellables. It's created lazily, so there's impact if not used.
  • Extend Publisher.handleEvents to add two new hooks:
    • receiveTermination: When either a completion or a cancellation is received
    • receiveResult: Takes a Result, and called when either values are received or an error is received
  • Add Publisher.promoteOptional()
  • Add then(receiveResult:), which takes a closure with a Result, allowing to handle values & error in the same place
  • Add sinkForLifetimeOf(_:) methods family, allowing to sink on a publisher and link to the lifetime of a given CombineExtensionsProvider & AnyObject. The goal of this is to avoid having to write the classic boilerplate code in Combine handling with having to create cancellables for every single object (this used the cancellables extension mentioned above).
  • Add performDuringLifetimeOf(_:action:), allowing to link an action with the lifetime of an object. This act as an equivalent for makeBindingTarget when calling functions or assigning multiple variables, for example:
extension Reactive where Base: UIViewController {
	func presentError<Error: Swift.Error>(animated: Bool = true) -> BindingTarget<Error> {
		self.makeBindingTarget {
			$0.present(error: $1, animated: animated)
		}
	}
}

becomes:

extension Publisher where Output: Error {
	func presentError(from viewController: UIViewController) {
		self.performDuringLifetimeOf(viewController) {
			$0.present(error: $1)
		}
	}
}

In usage, it's a bit different as well:

self.reactive.presentError() <~ self.viewModel.loginAction.errors

becomes

self.viewModel.loginAction.errors.presentError(from: self)

For assigning a single variable, see below.

  • Add assign(to:forLifetimeOf:), allowing to assign the output of the producer to a keyPath, keeping it alive until the specified object is deallocated. For example:
self.scanningLoader.reactive.isHidden <~ self.viewModel.scanAction.isExecuting.negate()

Becomes

self.viewModel.scanAction.$isExecuting.map { !$0 }
	.assign(to: \.scanningLoader.isHidden, forLifetimeOf: self)
  • Add TapAction and <UIControl>.combineExtensions.tapped, allowing to link an Action to a button, without having to do the bindings manually (similar to UIButton.reactive.pressed in ReactiveCocoa)
  • Add <UIControl>.publisherForControlEvent(_:), to get a publisher that triggers on any control events.
  • Add (UITextField/UITextView).(textValues|continuousTextValues), which are equivalent to same thing as for ReactiveCocoa.

Backwards-compatibility:

The original TapAction, OverridingAction and AnyAction were all prefixed with Reactive.


I'm looking forward to getting some feedback, about anything (naming, helpers, how it's done, why it's done, etc)! The goal here is to make programming with Combine when using UIKit as nice as working with the ReactiveSwift/ReactiveCocoa combo.

Depends on #53

@codecov
Copy link

codecov bot commented Oct 15, 2020

Codecov Report

Merging #54 into develop will increase coverage by 4.65%.
The diff coverage is 26.39%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop      #54      +/-   ##
===========================================
+ Coverage     7.34%   12.00%   +4.65%     
===========================================
  Files           60       71      +11     
  Lines         1729     2033     +304     
===========================================
+ Hits           127      244     +117     
- Misses        1602     1789     +187     
Impacted Files Coverage Δ
FueledUtils/Combine/AnyAction.swift 0.00% <0.00%> (ø)
FueledUtils/Combine/AnyCurrentValuePublisher.swift 0.00% <ø> (ø)
...Utils/Combine/CombineExtensions+Cancellables.swift 0.00% <0.00%> (ø)
FueledUtils/Combine/CombineExtensions.swift 0.00% <0.00%> (ø)
FueledUtils/Combine/OverridingAction.swift 0.00% <0.00%> (ø)
...ledUtils/CombineUIKit/ControlProtocol+Tapped.swift 0.00% <0.00%> (ø)
FueledUtils/CombineUIKit/TapAction.swift 0.00% <0.00%> (ø)
...ombineUIKit/UIControl+ControlEventsPublisher.swift 0.00% <0.00%> (ø)
FueledUtils/CombineUIKit/UITextInput+Combine.swift 0.00% <0.00%> (ø)
FueledUtils/ReactiveSwift/ReactiveAnyAction.swift 0.00% <ø> (ø)
... and 22 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 484b505...44e6c2e. Read the comment docs.

@stephanecopin stephanecopin force-pushed the feat/combine-additions branch 7 times, most recently from 44e6c2e to 588a141 Compare October 16, 2020 20:23
@stephanecopin stephanecopin force-pushed the feat/combine-additions branch 2 times, most recently from 44e6c2e to 588a141 Compare October 16, 2020 20:39
Copy link
Contributor

@notbenoit notbenoit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks solid! And the amount of documentation provided is a nice to have 👍

@stephanecopin stephanecopin merged commit bafa006 into develop Oct 21, 2020
@stephanecopin stephanecopin deleted the feat/combine-additions branch October 21, 2020 19:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants