Skip to content

Instantly share code, notes, and snippets.

@jasdev
Last active April 20, 2020 15:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jasdev/48e306c2e59dbe448620e5c89e3c958a to your computer and use it in GitHub Desktop.
Save jasdev/48e306c2e59dbe448620e5c89e3c958a to your computer and use it in GitHub Desktop.
A sample `AddressService`.
final class AddressService { /// (1) A hypothetical address service that exposes a publisher of `Address`s,
/// both from GPS and manual entry.
// MARK: - Inputs
let addressEntry = PassthroughSubject<Address, AddressError>() /// (2) For sake on example, let’s imagine a
/// `TextField` is bound to this subject so that in a location-related application, users can _manually_
/// enter an address.
// MARK: - Outputs
let addressToDisplay: AnyPublisher<Address, AddressError> /// (3) A publisher that merges[^1] both manual
/// address entry and those from the network.
/* … */
init() {
addressToDisplay = guessedAddressFromGeolocaton()
.multicast(subject: addressEntry) /// (3) Leaning on the `multicast(subject:)` overload.
.autoconnect()^ /// (4) Two notes here. First, `multicast` returns a `Publishers.Multicast`,
/// which conforms to the [`ConnectablePublisher` protocol](https://developer.apple.com/documentation/combine/connectablepublisher).
/// I’ll dig into what this means, below, but for now, this `autoconnect` call restores
/// ordinary `Publisher` behavior.
///
/// And second, the operator in the room, `^`. It’s postfix shorthand for `eraseToAnyPublisher`.
/// I know custom operators can be a holy war, but I discussed my liking of this one in an
/// [earlier diary entry](https://jasdev.me/notes/postfix-erasure).
/* … */
}
}
private func guessedAddressFromGeolocaton() -> AnyPublisher<Address, AddressError> { /* … */ } /// (5) A publisher that
/// emits address guesses based on location.
/// [^1] (footnote from `(3)`): Another approach to `init`’s body is to lean on the
/// [`merge` operator](https://developer.apple.com/documentation/combine/publisher/3204724-merge).
/// And, we could! But, to do so, safely, we’d need to rely on `share`, which is what I’m trying to
/// sketch out.
///
/// For the curious,
///
/// ```swift
/// addressToDisplay = guessedAddressFromGeolocaton()
/// .share()
/// .merge(with: addressEntry)^
/// ```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment