ValueObservation
public struct ValueObservation<Reducer>
ValueObservation tracks changes in the results of database requests, and notifies fresh values whenever the database changes.
For example:
let observation = Player.observationForAll()
let observer = try observation.start(in: dbQueue) { 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
-
scheduling
controls how fresh values are notified. Default is.mainQueue
..mainQueue
: all values are notified on the main queue.If the observation starts on the main queue, an initial value is notified right upon subscription, synchronously::
// On main queue let observation = Player.observationForAll() let observer = try observation.start(in: dbQueue) { players: [Player] in print("fresh players: \(players)") } // <- here "fresh players" is already printed.
If the observation does not start on the main queue, an initial value is also notified on the main queue, but asynchronously:
// Not on the main queue: "fresh players" is eventually printed // on the main queue. let observation = Player.observationForAll() let observer = try observation.start(in: dbQueue) { players: [Player] in print("fresh players: \(players)") }
When the database changes, fresh values are asynchronously notified:
// Eventually prints "fresh players" on the main queue try dbQueue.write { db in try Player(...).insert(db) }
.onQueue(_:startImmediately:)
: all values are asychronously notified on the specified queue.An initial value is fetched and notified if
startImmediately
is true.unsafe(startImmediately:)
: values are not all notified on the same dispatch queue.If
startImmediately
is true, an initial value is notified right upon subscription, synchronously, on the dispatch queue which starts the observation.// On any queue var observation = Player.observationForAll() observation.scheduling = .unsafe(startImmediately: true) let observer = try observation.start(in: dbQueue) { players: [Player] in print("fresh players: \(players)") } // <- here "fresh players" is already printed.
When the database changes, other values are notified on unspecified queues.
Declaration
Swift
public var scheduling: ValueScheduling
-
Creates a ValueObservation which observes request, and notifies its count whenever it is modified by a database transaction.
For example:
let request = Player.all() let observation = ValueObservation.trackingCount(request) let observer = try observation.start(in: dbQueue) { count: Int in print("Number of players has changed") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
@available(*, deprecated, message: "Use request.observationForCount(﹚ instead") public static func trackingCount<Request: FetchRequest>(_ request: Request) -> ValueObservation<ValueReducers.RemoveDuplicates<ValueReducers.Fetch<Int>>>
Parameters
request
the observed request.
Return Value
a ValueObservation.
- When started with the
-
Creates a ValueObservation which observes request, and notifies fresh values whenever the request is modified by a database transaction.
For example:
let request = Player.select(Column("name"), as: String.self) let observation = ValueObservation.trackingAll(request) let observer = try observation.start(in: dbQueue) { names: [String] in print("Player names have changed") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
@available(*, deprecated, message: "Use request.observationForAll(﹚ instead") public static func trackingAll<Request: FetchRequest>(_ request: Request) -> ValueObservation<DatabaseValuesReducer<Request.RowDecoder>> where Request.RowDecoder: DatabaseValueConvertible
Parameters
request
the observed request.
Return Value
a ValueObservation.
- When started with the
-
Creates a ValueObservation which observes request, and notifies a fresh value whenever the request is modified by a database transaction.
For example:
let request = Player.select(max(Column("score")), as: Int.self) let observation = ValueObservation.trackingOne(request) let observer = try observation.start(in: dbQueue) { maxScore: Int? in print("Maximum score has changed") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
@available(*, deprecated, message: "Use request.observationForFirst(﹚ instead") public static func trackingOne<Request: FetchRequest>(_ request: Request) -> ValueObservation<DatabaseValueReducer<Request.RowDecoder>> where Request.RowDecoder: DatabaseValueConvertible
Parameters
request
the observed request.
Return Value
a ValueObservation.
- When started with the
-
Creates a ValueObservation which observes request, and notifies fresh values whenever the request is modified by a database transaction.
For example:
let request = Player.select(Column("name"), as: Optional<String>.self) let observation = ValueObservation.trackingAll(request) let observer = try observation.start(in: dbQueue) { names: [String?] in print("Player names have changed") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
@available(*, deprecated, message: "Use request.observationForAll(﹚ instead") public static func trackingAll<Request: FetchRequest>(_ request: Request) -> ValueObservation<OptionalDatabaseValuesReducer<Request.RowDecoder._Wrapped>> where Request.RowDecoder: _OptionalProtocol, Request.RowDecoder._Wrapped: DatabaseValueConvertible
Parameters
request
the observed request.
Return Value
a ValueObservation.
- When started with the
-
Creates a ValueObservation which observes request, and notifies fresh records whenever the request is modified by a database transaction.
For example:
let request = Player.all() let observation = ValueObservation.trackingAll(request) let observer = try observation.start(in: dbQueue) { players: [Player] in print("Players have changed") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
@available(*, deprecated, message: "Use request.observationForAll(﹚ instead") public static func trackingAll<Request: FetchRequest>(_ request: Request) -> ValueObservation<FetchableRecordsReducer<Request.RowDecoder>> where Request.RowDecoder: FetchableRecord
Parameters
request
the observed request.
Return Value
a ValueObservation.
- When started with the
-
Creates a ValueObservation which observes request, and notifies a fresh record whenever the request is modified by a database transaction.
For example:
let request = Player.filter(key: 1) let observation = ValueObservation.trackingOne(request) let observer = try observation.start(in: dbQueue) { player: Player? in print("Player has changed") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
@available(*, deprecated, message: "Use request.observationForFirst(﹚ instead") public static func trackingOne<Request: FetchRequest>(_ request: Request) -> ValueObservation<FetchableRecordReducer<Request.RowDecoder>> where Request.RowDecoder: FetchableRecord
Parameters
request
the observed request.
Return Value
a ValueObservation.
- When started with the
-
Returns a ValueObservation with a transformed reducer.
Declaration
Swift
public func mapReducer<R>(_ transform: @escaping (Database, Reducer) throws -> R) -> ValueObservation<R>
-
Creates a ValueObservation which observes request, and notifies fresh rows whenever the request is modified by a database transaction.
For example:
let request = SQLRequest<Row>(sql: "SELECT * FROM player") let observation = ValueObservation.trackingAll(request) let observer = try observation.start(in: dbQueue) { rows: [Row] in print("Players have changed") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
@available(*, deprecated, message: "Use request.observationForAll(﹚ instead") public static func trackingAll<Request: FetchRequest>(_ request: Request) -> ValueObservation<RowsReducer> where Request.RowDecoder == Row
Parameters
request
the observed request.
Return Value
a ValueObservation.
- When started with the
-
Creates a ValueObservation which observes request, and notifies a fresh row whenever the request is modified by a database transaction.
For example:
let request = SQLRequest<Row>(sql: "SELECT * FROM player WHERE id = ?", arguments: [1]) let observation = ValueObservation.trackingOne(request) let observer = try observation.start(in: dbQueue) { row: Row? in print("Players have changed") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
@available(*, deprecated, message: "Use request.observationForFirst(﹚ instead") public static func trackingOne<Request: FetchRequest>(_ request: Request) -> ValueObservation<RowReducer> where Request.RowDecoder == Row
Parameters
request
the observed request.
Return Value
a ValueObservation.
- When started with the
-
Starts the value observation in the provided database reader (such as a database queue or database pool), and returns a transaction observer.
Declaration
Swift
public func start( in reader: DatabaseReader, onChange: @escaping (Reducer.Value) -> Void) throws -> TransactionObserver
Parameters
reader
A DatabaseReader.
onChange
A closure that is provided fresh values
Return Value
a TransactionObserver
-
Starts the value observation in the provided database reader (such as a database queue or database pool), and returns a transaction observer.
Declaration
Swift
public func start( in reader: DatabaseReader, onError: @escaping (Error) -> Void, onChange: @escaping (Reducer.Value) -> Void) -> TransactionObserver
Parameters
reader
A DatabaseReader.
onError
A closure that is provided eventual errors that happen during observation
onChange
A closure that is provided fresh values
Return Value
a TransactionObserver
-
Returns a ValueObservation which observes regions, and notifies the values returned by the reducer whenever one of the observed regions is modified by a database transaction.
This method is the most fundamental way to create a ValueObservation.
For example, this observation counts the number of a times the player table is modified:
var count = 0 let reducer = AnyValueReducer( fetch: { _ in /* don't fetch anything */ }, value: { _ -> Int? in defer { count += 1 } return count }) let observation = ValueObservation.tracking(Player.all(), reducer: { db in reducer }) let observer = observation.start(in: dbQueue) { count: Int in print("Players have been modified \(count) times.") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
public static func tracking( _ regions: DatabaseRegionConvertible..., reducer: @escaping (Database) throws -> Reducer) -> ValueObservation
Parameters
regions
A list of observed regions.
reducer
A reducer that turns database changes in the modified regions into fresh values. Currently only reducers that adopt the ValueReducer protocol are supported.
- When started with the
-
Returns a ValueObservation which observes regions, and notifies the values returned by the reducer whenever one of the observed regions is modified by a database transaction.
This method is the most fundamental way to create a ValueObservation.
For example, this observation counts the number of a times the player table is modified:
var count = 0 let reducer = AnyValueReducer( fetch: { _ in /* don't fetch anything */ }, value: { _ -> Int? in defer { count += 1 } return count }) let observation = ValueObservation.tracking([Player.all()], reducer: { db in reducer }) let observer = observation.start(in: dbQueue) { count: Int in print("Players have been modified \(count) times.") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
public static func tracking( _ regions: [DatabaseRegionConvertible], reducer: @escaping (Database) throws -> Reducer) -> ValueObservation
Parameters
regions
A list of observed regions.
reducer
A reducer that turns database changes in the modified regions into fresh values. Currently only reducers that adopt the ValueReducer protocol are supported.
- When started with the
-
Creates a ValueObservation which notifies the values returned by the fetch closure whenever a database transaction changes them.
For example:
let observation = ValueObservation.tracking { db in try Player.fetchAll(db) } let observer = try observation.start(in: dbQueue) { players: [Player] in print("Players have changed") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
public static func tracking<Value>( value: @escaping (Database) throws -> Value) -> ValueObservation<ValueReducers.Fetch<Value>>
Parameters
value
A closure that fetches a value.
- When started with the
-
Creates a ValueObservation which observes regions, and notifies the values returned by the fetch closure whenever one of the observed regions is modified by a database transaction.
For example:
let observation = ValueObservation.tracking( Player.all(), fetch: { db in return try Player.fetchAll(db) }) let observer = try observation.start(in: dbQueue) { players: [Player] in print("Players have changed") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
public static func tracking<Value>( _ regions: DatabaseRegionConvertible..., fetch: @escaping (Database) throws -> Value) -> ValueObservation<ValueReducers.Fetch<Value>>
Parameters
regions
A list of observed regions.
fetch
A closure that fetches a value.
- When started with the
-
Creates a ValueObservation which observes regions, and notifies the values returned by the fetch closure whenever one of the observed regions is modified by a database transaction.
For example:
let observation = ValueObservation.tracking( [Player.all()], fetch: { db in return try Player.fetchAll(db) }) let observer = try observation.start(in: dbQueue) { players: [Player] in print("Players have changed") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
public static func tracking<Value>( _ regions: [DatabaseRegionConvertible], fetch: @escaping (Database) throws -> Value) -> ValueObservation<ValueReducers.Fetch<Value>>
Parameters
regions
A list of observed regions.
fetch
A closure that fetches a value.
- When started with the
-
Undocumented
Declaration
Swift
public static func combine< R1: ValueReducer, R2: ValueReducer>( _ o1: ValueObservation<R1>, _ o2: ValueObservation<R2>) -> ValueObservation<ValueReducers.Combine2<R1, R2>>
-
Undocumented
Declaration
Swift
public func combine< R1: ValueReducer, Combined>( _ other: ValueObservation<R1>, _ transform: @escaping (Reducer.Value, R1.Value) -> Combined) -> ValueObservation<ValueReducers.Map<ValueReducers.Combine2<Reducer, R1>, Combined>>
-
Undocumented
Declaration
Swift
public static func combine< R1: ValueReducer, R2: ValueReducer, R3: ValueReducer>( _ o1: ValueObservation<R1>, _ o2: ValueObservation<R2>, _ o3: ValueObservation<R3>) -> ValueObservation<ValueReducers.Combine3<R1, R2, R3>>
-
Undocumented
Declaration
Swift
public func combine< R1: ValueReducer, R2: ValueReducer, Combined>( _ observation1: ValueObservation<R1>, _ observation2: ValueObservation<R2>, _ transform: @escaping (Reducer.Value, R1.Value, R2.Value) -> Combined) -> ValueObservation<ValueReducers.Map<ValueReducers.Combine3<Reducer, R1, R2>, Combined>>
-
Undocumented
Declaration
Swift
public static func combine< R1: ValueReducer, R2: ValueReducer, R3: ValueReducer, R4: ValueReducer>( _ o1: ValueObservation<R1>, _ o2: ValueObservation<R2>, _ o3: ValueObservation<R3>, _ o4: ValueObservation<R4>) -> ValueObservation<ValueReducers.Combine4<R1, R2, R3, R4>>
-
Undocumented
Declaration
Swift
public func combine< R1: ValueReducer, R2: ValueReducer, R3: ValueReducer, Combined>( _ observation1: ValueObservation<R1>, _ observation2: ValueObservation<R2>, _ observation3: ValueObservation<R3>, _ transform: @escaping (Reducer.Value, R1.Value, R2.Value, R3.Value) -> Combined) -> ValueObservation<ValueReducers.Map<ValueReducers.Combine4<Reducer, R1, R2, R3>, Combined>>
-
Undocumented
Declaration
Swift
public static func combine< R1: ValueReducer, R2: ValueReducer, R3: ValueReducer, R4: ValueReducer, R5: ValueReducer>( _ o1: ValueObservation<R1>, _ o2: ValueObservation<R2>, _ o3: ValueObservation<R3>, _ o4: ValueObservation<R4>, _ o5: ValueObservation<R5>) -> ValueObservation<ValueReducers.Combine5<R1, R2, R3, R4, R5>>
-
Undocumented
Declaration
Swift
public func combine< R1: ValueReducer, R2: ValueReducer, R3: ValueReducer, R4: ValueReducer, Combined>( _ observation1: ValueObservation<R1>, _ observation2: ValueObservation<R2>, _ observation3: ValueObservation<R3>, _ observation4: ValueObservation<R4>, _ transform: @escaping (Reducer.Value, R1.Value, R2.Value, R3.Value, R4.Value) -> Combined) -> ValueObservation<ValueReducers.Map<ValueReducers.Combine5<Reducer, R1, R2, R3, R4>, Combined>>
-
Undocumented
Declaration
Swift
public static func combine< R1: ValueReducer, R2: ValueReducer, R3: ValueReducer, R4: ValueReducer, R5: ValueReducer, R6: ValueReducer>( _ o1: ValueObservation<R1>, _ o2: ValueObservation<R2>, _ o3: ValueObservation<R3>, _ o4: ValueObservation<R4>, _ o5: ValueObservation<R5>, _ o6: ValueObservation<R6>) -> ValueObservation<ValueReducers.Combine6<R1, R2, R3, R4, R5, R6>>
-
Undocumented
Declaration
Swift
public static func combine< R1: ValueReducer, R2: ValueReducer, R3: ValueReducer, R4: ValueReducer, R5: ValueReducer, R6: ValueReducer, R7: ValueReducer>( _ o1: ValueObservation<R1>, _ o2: ValueObservation<R2>, _ o3: ValueObservation<R3>, _ o4: ValueObservation<R4>, _ o5: ValueObservation<R5>, _ o6: ValueObservation<R6>, _ o7: ValueObservation<R7>) -> ValueObservation<ValueReducers.Combine7<R1, R2, R3, R4, R5, R6, R7>>
-
Undocumented
Declaration
Swift
public static func combine< R1: ValueReducer, R2: ValueReducer, R3: ValueReducer, R4: ValueReducer, R5: ValueReducer, R6: ValueReducer, R7: ValueReducer, R8: ValueReducer>( _ o1: ValueObservation<R1>, _ o2: ValueObservation<R2>, _ o3: ValueObservation<R3>, _ o4: ValueObservation<R4>, _ o5: ValueObservation<R5>, _ o6: ValueObservation<R6>, _ o7: ValueObservation<R7>, _ o8: ValueObservation<R8>) -> ValueObservation<ValueReducers.Combine8<R1, R2, R3, R4, R5, R6, R7, R8>>
-
Returns a ValueObservation which notifies the non-nil results of calling the given transformation which each element notified by this value observation.
Declaration
Swift
public func compactMap<T>(_ transform: @escaping (Reducer.Value) -> T?) -> ValueObservation<ValueReducers.CompactMap<Reducer, T>>
-
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>>
-
Returns a ValueObservation which filters out consecutive equal values.
Declaration
Swift
@available(*, deprecated, renamed: "removeDuplicates") public func distinctUntilChanged() -> ValueObservation<ValueReducers.RemoveDuplicates<Reducer>>
-
Returns a ValueObservation which filters out consecutive equal values.
Declaration
Swift
public func removeDuplicates() -> ValueObservation<ValueReducers.RemoveDuplicates<Reducer>>