WWDC2019 Combine in Practice

3227 ワード

単純にPublisherの出力をJSONにエンコード
.decode(MagicTrick.self, JSONDecoder())

Failure Handling Operators

assertNoFailure
retry
catch
mapError
setFailureType

次のコードで失敗したときにPublisherを置き換えることができます.
.flatMap { data in
    return Just(data)
        .decode(MagicTrick.self, JSONDecoder())
        .catch {
            return Just(MagicTrick.placeholder)// 
         }
}
.publisher(for: \.name)// Publisher

Scheduled Operators

delay// 
debounce// 
throttle
receive(on:)// 
subscribe(on:)

Scheduler describers ·When ·Where Supported by RunLoop and DispatchQueue

タスクのキャンセル

// Using Subscribers with Combine
let trickNamePublisher = ...
let canceller = trickNamePublisher.assign(to: \.someProperty, on: someObject)

//...
canceller.cancel()


Built into Combine Terminate subscriptions early
自動実行cancel deinitの場合
protocol Cancellable {
    func cancel()
}
final class AnyCancellable: Cancellable {} //Calls 'cancel' on deinit

Subjects


Behave like both Publisher and Subscriber Broadcast values to multiple subscribers
protocol Subject: Publisher, AnyObject {
    func send(_ value: Output)
    func send(completion: Subscribers.Completion)
}
// Using Subjects with Combine
let trickNamePublisher = ... // Publisher of 

let magicWordsSubject = PassthroughSubject()

trickNamePublisher.subscribe(magicWordsSubject)

let canceller = magicWordsSubject.sink { value in
    // do something with the value
}

magicWordsSubject.send("Please")

let sharedTrickNamePublisher = trickNamePublisher.share()

Working with SwiftUI


SwiftUI owns the Subscriber You just need to bring a Publisher
SwiftUI BindableObject
// SwiftUI 
protocol BindableObject {
    associatedtype PublisherType : Publisher where PublisherType.Failure == Never
    var didChange: PublisherType { get } 
}
// you can see more things in
Data Flow in SwiftUI WWDC 2019
// Combine with SwiftUI
class WizardModel : BindableObject {
    var trick: WizardTrick { didSet { didChange.send() }
    var wand: Wand? { didSet { didChange.send() }

    let didChange = PassthroughSubject()
}

@Published


Property wrapper Adds a publisher to any property
//Using @Published
@Published var password: String = ""

self.password = "1234"

let currentPassword: String = self.password

let printerSubscription = $password.sink {
    print("The published value is '\($0)'") // now is "password"
}

self.password = "password" 

Debounce


Use Combine Today


Compose small parts into custom publishers Adopt incrementally Add a Publisher to a property with @Published Compose callbacks and Publishers with Future