Skip to content

Instantly share code, notes, and snippets.

@niazoff
Created January 2, 2020 14:18
Show Gist options
  • Save niazoff/83e842ddd07b311494d747e0728218dc to your computer and use it in GitHub Desktop.
Save niazoff/83e842ddd07b311494d747e0728218dc to your computer and use it in GitHub Desktop.
Introduction to Combine using Instagram analogy
import Foundation
import Combine
struct Post {
let imageName: String
let description: String?
init(imageName: String, description: String? = nil) {
self.imageName = imageName
self.description = description
}
}
enum UserError: Error {}
struct User: Publisher {
typealias Output = Post
typealias Failure = UserError
func receive<S>(subscriber: S) where S: Subscriber, Failure == S.Failure, Output == S.Input {
subscriber.receive(subscription: UserSubscription(subscriber: subscriber))
}
}
class UserSubscription<S: Subscriber>: Subscription where User.Failure == S.Failure, User.Output == S.Input {
private let posts = [
Post(imageName: "Mountain"),
Post(imageName: "Coffee"),
Post(imageName: "Desert"),
Post(imageName: "City")
]
private var subscriber: S?
init(subscriber: S) { self.subscriber = subscriber }
func request(_ demand: Subscribers.Demand) {
var posts = self.posts
var currentDemand = demand
while currentDemand != .none && !posts.isEmpty {
let post = posts.removeFirst()
if let addedDemand = subscriber?.receive(post) {
currentDemand -= 1
currentDemand += addedDemand
}
}
subscriber?.receive(completion: .finished)
}
func cancel() { subscriber = nil }
}
class Follower: Subscriber {
typealias Input = Post
typealias Failure = UserError
func receive(subscription: Subscription) {
subscription.request(.unlimited)
}
func receive(_ post: Post) -> Subscribers.Demand {
print(post)
return .none
}
func receive(completion: Subscribers.Completion<UserError>) {
print(completion)
}
}
let user = User()
var follower = Follower()
user.receive(subscriber: follower)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment