Combine -- Foundation 中的 Publisher

URLSession Publisher

URLSession 的 dataTaskPublisher(for:) 方法可以直接返回一个 Publisher,它会在网络请求成功时发布一个值为 (Data, URLResponse) 的事件,请求过程失败时,发送类型为 URLError 的错误。

struct Response: Decodable {
    struct Args: Decodable {
        let foo: String
    }
    
    let args: Args?
}

URLSession.shared
    .dataTaskPublisher(for: URL(string: "https://httpbin.org/get?foo=bar")!)
    .map{ data, _ in data }
    .decode(type: Response.self, decoder: JSONDecoder())
    .compactMap{$0.args?.foo}
    .subscribe(on: RunLoop.main)
    .print()
    .sink(receiveCompletion: {_ in}) { (foo) in
        print(foo)
    }

// receive subscription: (SubscribeOn)
// request unlimited
// receive value: (bar)
// bar
// receive finished

Timer Publisher

Foundation 中的 Timer 类型也提供了一个方法,来创建一个按照一定间隔发送事件的 Publisher,TimerPublisher 的 Output 是 Date :

extension Timer {

    /// Returns a publisher that repeatedly emits the current date on the given interval.
    ///
    /// - Parameters:
    ///   - interval: The time interval on which to publish events. For example, a value of `0.5` publishes an event approximately every half-second.
    ///   - tolerance: The allowed timing variance when emitting events. Defaults to `nil`, which allows any variance.
    ///   - runLoop: The run loop on which the timer runs.
    ///   - mode: The run loop mode in which to run the timer.
    ///   - options: Scheduler options passed to the timer. Defaults to `nil`.
    /// - Returns: A publisher that repeatedly emits the current date on the given interval.
    public static func publish(
        every interval: TimeInterval, 
        tolerance: TimeInterval? = nil, 
        on runLoop: RunLoop, 
        in mode: RunLoop.Mode, 
        options: RunLoop.SchedulerOptions? = nil
    ) -> Timer.TimerPublisher
}

Notification Publisher

extension NotificationCenter { 
        public func publisher(
                for name: Notification.Name, 
                object: AnyObject? = nil 
        ) ->  NotificationCenter.Publisher 
}

NotificationCenter.Publisher 的 Output 值是 Notification

@Published

Combine 中存在 @Published 封装,用来把一个 class 的属性值转变为 Publisher。它同时提供了值的存储和对外的 Publisher (通过投影符号 $ 获取)。在被订阅时,当前值也会被发送给订阅者,它的底层其实就是一个 CurrentValueSubject

class Wrapper {
    @Published var text: String = "hhoo"
}
var wrapper = Wrapper()
wrapper.$text.print().sink { _ in }
wrapper.text = "1222"

// receive subscription: (CurrentValueSubject)
// request unlimited
// receive value: (hhoo)
// receive value: (1222)
// receive cancel

你可能感兴趣的:(Combine -- Foundation 中的 Publisher)