ValueObservation

public struct ValueObservation<Reducer> where Reducer : ValueReducer

ValueObservation tracks changes in the results of database requests, and notifies fresh values whenever the database changes.

For example:

let observation = ValueObservation.tracking { db in
    try Player.fetchAll(db)
}

let cancellable = try observation.start(
    in: dbQueue,
    onError: { error in ... },
    onChange: { players: [Player] in
        print("Players have changed.")
    })
  • Default is false. Set this property to true when the observation requires write access in order to fetch fresh values. Fetches are then wrapped inside a savepoint.

    Don’t set this flag to true unless you really need it. A read/write observation is less efficient than a read-only observation.

    Declaration

    Swift

    public var requiresWriteAccess: Bool

Starting Observation

  • Starts the value observation in the provided database reader (such as a database queue or database pool).

    The observation lasts until the returned cancellable is cancelled or deallocated.

    For example:

    let observation = ValueObservation.tracking { db in
        try Player.fetchAll(db)
    }
    
    let cancellable = try observation.start(
        in: dbQueue,
        onError: { error in ... },
        onChange: { players: [Player] in
            print("fresh players: \(players)")
        })
    

    By default, fresh values are dispatched asynchronously on the main queue. You can change this behavior by providing a scheduler. For example, .immediate notifies all values on the main queue as well, and the first one is immediately notified when the start() method is called:

    let cancellable = try observation.start(
        in: dbQueue,
        scheduling: .immediate, // <-
        onError: { error in ... },
        onChange: { players: [Player] in
            print("fresh players: \(players)")
        })
    // <- here "fresh players" is already printed.
    

    Declaration

    Swift

    public func start(
        in reader: DatabaseReader,
        scheduling scheduler: ValueObservationScheduler = .async(onQueue: .main),
        onError: @escaping (Error) -> Void,
        onChange: @escaping (Reducer.Value) -> Void) -> DatabaseCancellable

    Parameters

    reader

    A DatabaseReader.

    scheduler

    A Scheduler. By default, fresh values are dispatched asynchronously on the main queue.

    onError

    A closure that is provided eventual errors that happen during observation

    onChange

    A closure that is provided fresh values

    Return Value

    a DatabaseCancellable

Debugging

  • Performs the specified closures when ValueObservation events occur.

    Declaration

    Swift

    public func handleEvents(
        willStart: (() -> Void)? = nil,
        willFetch: (() -> Void)? = nil,
        willTrackRegion: ((DatabaseRegion) -> Void)? = nil,
        databaseDidChange: (() -> Void)? = nil,
        didReceiveValue: ((Reducer.Value) -> Void)? = nil,
        didFail: ((Error) -> Void)? = nil,
        didCancel: (() -> Void)? = nil)
        -> ValueObservation<ValueReducers.Trace<Reducer>>

    Parameters

    willStart

    A closure that executes when the observation starts. Defaults to nil.

    willFetch

    A closure that executes when the observed value is about to be fetched. Defaults to nil.

    willTrackRegion

    A closure that executes when the observation starts tracking a database region. Defaults to nil.

    databaseDidChange

    A closure that executes after the observation was impacted by a database change. Defaults to nil.

    didReceiveValue

    A closure that executes on fresh values. Defaults to nil.

    didFail

    A closure that executes when the observation fails. Defaults to nil.

    didCancel

    A closure that executes when the observation is cancelled. Defaults to nil.

    Return Value

    A ValueObservation that performs the specified closures when ValueObservation events occur.

  • Prints log messages for all ValueObservation events.

    Declaration

    Swift

    public func print(
        _ prefix: String = "",
        to stream: TextOutputStream? = nil)
        -> ValueObservation<ValueReducers.Trace<Reducer>>

Publishing Observed Values

  • Creates a publisher which tracks changes in database values.

    For example:

    let observation = ValueObservation.tracking { db in
        try Player.fetchAll(db)
    }
    let cancellable = observation
        .publisher(in: dbQueue)
        .sink(
            receiveCompletion: { completion in ... },
            receiveValue: { players: [Player] in
                print("fresh players: \(players)")
            })
    

    By default, fresh values are dispatched asynchronously on the main queue. You can change this behavior by by providing a scheduler.

    For example, .immediate notifies all values on the main queue as well, and the first one is immediately notified when the publisher is subscribed:

    let cancellable = observation
        .publisher(
            in: dbQueue,
            scheduling: .immediate) // <-
        .sink(
            receiveCompletion: { completion in ... },
            receiveValue: { players: [Player] in
                print("fresh players: \(players)")
            })
    // <- here "fresh players" is already printed.
    

    Note that the .immediate scheduler requires that the publisher is subscribed from the main thread. It raises a fatal error otherwise.

    Declaration

    Swift

    @available(OSX 10.15, iOS 13, tvOS 13, watchOS 6, *)
    public func publisher(
        in reader: DatabaseReader,
        scheduling scheduler: ValueObservationScheduler = .async(onQueue: .main))
        -> DatabasePublishers.Value<Reducer.Value>

    Parameters

    reader

    A DatabaseReader.

    scheduler

    A Scheduler. By default, fresh values are dispatched asynchronously on the main queue.

    Return Value

    A Combine publisher

  • Returns a ValueObservation which notifies the results of calling the given transformation which each element notified by this value observation.

    Declaration

    Swift

    public func map<T>(_ transform: @escaping (Reducer.Value) -> T)
        -> ValueObservation<ValueReducers.Map<Reducer, T>>

Creating ValueObservation

  • Creates a ValueObservation which notifies the values returned by the fetch function whenever a database transaction changes them.

    The fetch function must always performs the same database requests. The stability of the observed database region allows optimizations.

    When you want to observe a varying database region, use the ValueObservation.trackingVaryingRegion(_:) method instead.

    For example:

    let observation = ValueObservation.tracking { db in
        try Player.fetchAll(db)
    }
    
    let cancellable = try observation.start(
        in: dbQueue,
        onError: { error in ... },
        onChange:) { players: [Player] in
            print("Players have changed")
        })
    

    Declaration

    Swift

    public static func tracking<Value>(
        _ fetch: @escaping (Database) throws -> Value)
        -> ValueObservation<ValueReducers.Fetch<Value>>

    Parameters

    fetch

    A function that fetches the observed value from the database.

  • Creates a ValueObservation which notifies the values returned by the fetch function whenever a database transaction changes them.

    Declaration

    Swift

    public static func trackingVaryingRegion<Value>(
        _ fetch: @escaping (Database) throws -> Value)
        -> ValueObservation<ValueReducers.Fetch<Value>>

    Parameters

    fetch

    A function that fetches the observed value from the database.

Available where Reducer.Value: Equatable