Core Concepts of Combine

Publisher, Subscriber, Operators and Subjects

Image for post
Image for post
Photo by Paweł Czerwiński on Unsplash

What is Combine?

Image for post
Image for post
Image for post
Image for post

Understood. Let me describe them:

The core concepts

Publishers

Subscribers

Operators

Image for post
Image for post

The Examples

let myPublisher = Just(13)
let subscribeMyPublisher = myPublisher.sink { int in
print("Value: \(int)")
}
let empty = Empty<Int, Never>()let subscribeEmpty = empty.sink { int in
print(“Value: \(int)”)
}
let fail = Fail<Any, MyError>(error: MyError())
let myPublisher = Just(13)
let cancellable: AnyCancellable = myPublisher.sink(
receiveCompletion: { completion in
print("cancellable completion \(completion)")
},
receiveValue: { value in
print("cancellable value \(value)")
}
)
cancellable value 13
cancellable completion finished
let integerPublisher = [0, 1, 2, 3, 4, 5].publisherlet subscribeInteger = integerPublisher.sink { value in
print ("Values from integerPublisher \(value)")
}
let storeCancellable: AnyCancellable
storeCancellable = integerPublisher
.sink { value in
print (“Values from storeCancellable \(value)”)
}
var cancellableCollection = [AnyCancellable]()
integerPublisher
.sink { value in
print (“Values from storeCancellable \(value)”)
}.store(in: &cancellableCollection)
class LoginViewModel {
var shouldNav: AnyPublisher<Bool, Never>?
}
var passThroughSubject = PassthroughSubject<Int, Never>()let pass = passThroughSubject.sink( 
receiveValue: value in { print("passThroughSubject \(value)" ) }
)
passThroughSubject.send(1)
var currentSubject = CurrentValueSubject<Int, Never>(10)
let current = currentSubject.sink(receiveValue: { value in
print(“currentSubject \(value)” ) }
)
currentSubject.send(1)
print ( currentSubject.value )
currentSubject.value = 5
let passString = PassthroughSubject<String, MyError>()
let stringCancellable = passString.handleEvents(receiveSubscription: { (subscription) in
print("receiveSubscription!")
}, receiveOutput: { _ in
print("receiveOutput!")
}, receiveCompletion: { _ in
print("receiveCompletion")
}, receiveCancel: {
print("receiveCancel")
})
.replaceError(with: "Failure")
.sink { (value) in
print("Subscriber received value: \(value)")
}
passString.send("Hello, World!")
passString.send(completion: .failure(MyError()))
receiveSubscription!
receiveOutput!
Subscriber received value: Hello, World!
receiveCompletion
Subscriber received value: Failure
let usernamePublisher = PassthroughSubject<String, Never>()
let passwordPublisher = PassthroughSubject<String, Never>()
let validatCancellable = Publishers
.CombineLatest(usernamePublisher, passwordPublisher)
.map { (username, password) -> Bool in
username.count > 6 && password.count > 6
}
.eraseToAnyPublisher()
var userValidation: AnyPublisher<Bool, Never> {
validLengthUsername
.zip(validLengthPassword)
.map { $0 && $1 }
.eraseToAnyPublisher()
}
@Published var username: String = ""
var validLengthUsername: AnyPublisher<Bool, Never> {
return $username.debounce(for: 0.2, scheduler: RunLoop.main)
.removeDuplicates()
.map{$0.count >= passwordLength ? true : false}
.eraseToAnyPublisher()
}
let future = Future<Bool, Never> { promise in
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
promise(.success(true))
}
}
let fut = future.sink(
receiveCompletion:
{
val in
print(“Future \(val)”)
}
,
receiveValue: { val in
print(“Received \(val)”)
})

Bind to components

let validationSub = loginViewModel?.userValidation
.receive(on: RunLoop.main)
.assign(to: \.isEnabled, on: loginView.loginButton)

Debugging

Image for post
Image for post
let publisher = PassthroughSubject<String?, Never>()
let cancellable = publisher
.breakpoint(
receiveOutput: { value in return value == "DEBUGGER" }
)
.breakpointOnError()
.sink { print("\(String(describing: $0))" , terminator: " ") }
publisher.send("DEBUGGER")

Why would you use Combine, anyway?

Image for post
Image for post

Conclusion

Image for post
Image for post

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store