FetchedRecordsController

public final class FetchedRecordsController<Record> where Record : FetchableRecord

You use FetchedRecordsController to track changes in the results of an SQLite request.

See https://github.com/groue/GRDB.swift#fetchedrecordscontroller for more information.

Initialization

  • Creates a fetched records controller initialized from a SQL query and its eventual arguments.

    let controller = FetchedRecordsController<Wine>(
        dbQueue,
        sql: "SELECT * FROM wine WHERE color = ? ORDER BY name",
        arguments: [Color.red],
        isSameRecord: { (wine1, wine2) in wine1.id == wine2.id })
    

    Declaration

    Swift

    public convenience init(
        _ databaseWriter: DatabaseWriter,
        sql: String,
        arguments: StatementArguments = StatementArguments(),
        adapter: RowAdapter? = nil,
        queue: DispatchQueue = .main,
        isSameRecord: ((Record, Record) -> Bool)? = nil) throws

    Parameters

    databaseWriter

    A DatabaseWriter (DatabaseQueue, or DatabasePool)

    sql

    An SQL query.

    arguments

    Optional statement arguments.

    adapter

    Optional RowAdapter

    queue

    A serial dispatch queue (defaults to the main queue)

    The fetched records controller tracking callbacks will be notified of changes in this queue. The controller itself must be used from this queue.

    isSameRecord

    Optional function that compares two records.

    This function should return true if the two records have the same identity. For example, they have the same id.

  • Creates a fetched records controller initialized from a fetch request from the Query Interface.

    let request = Wine.order(Column("name"))
    let controller = FetchedRecordsController(
        dbQueue,
        request: request,
        isSameRecord: { (wine1, wine2) in wine1.id == wine2.id })
    

    Declaration

    Swift

    public convenience init<Request>(
        _ databaseWriter: DatabaseWriter,
        request: Request,
        queue: DispatchQueue = .main,
        isSameRecord: ((Record, Record) -> Bool)? = nil) throws
        where Request: FetchRequest, Request.RowDecoder == Record

    Parameters

    databaseWriter

    A DatabaseWriter (DatabaseQueue, or DatabasePool)

    request

    A fetch request.

    queue

    A serial dispatch queue (defaults to the main queue)

    The fetched records controller tracking callbacks will be notified of changes in this queue. The controller itself must be used from this queue.

    isSameRecord

    Optional function that compares two records.

    This function should return true if the two records have the same identity. For example, they have the same id.

  • Executes the controller’s fetch request.

    After executing this method, you can access the the fetched objects with the fetchedRecords property.

    This method must be used from the controller’s dispatch queue (the main queue unless stated otherwise in the controller’s initializer).

    Declaration

    Swift

    public func performFetch() throws

Configuration

  • The database writer used to fetch records.

    The controller registers as a transaction observer in order to respond to changes.

    Declaration

    Swift

    public let databaseWriter: DatabaseWriter
  • The dispatch queue on which the controller must be used.

    Unless specified otherwise at initialization time, it is the main queue.

    Declaration

    Swift

    public let queue: DispatchQueue
  • Updates the fetch request, and eventually notifies the tracking callbacks if performFetch() has been called.

    This method must be used from the controller’s dispatch queue (the main queue unless stated otherwise in the controller’s initializer).

    Declaration

    Swift

    public func setRequest<Request>(_ request: Request)
        throws
        where Request: FetchRequest, Request.RowDecoder == Record
  • Updates the fetch request, and eventually notifies the tracking callbacks if performFetch() has been called.

    This method must be used from the controller’s dispatch queue (the main queue unless stated otherwise in the controller’s initializer).

    Declaration

    Swift

    public func setRequest(
        sql: String,
        arguments: StatementArguments = StatementArguments(),
        adapter: RowAdapter? = nil)
        throws
  • Registers changes notification callbacks.

    This method must be used from the controller’s dispatch queue (the main queue unless stated otherwise in the controller’s initializer).

    Declaration

    Swift

    public func trackChanges(
        willChange: ((FetchedRecordsController<Record>) -> Void)? = nil,
        onChange: ((FetchedRecordsController<Record>, Record, FetchedRecordChange) -> Void)? = nil,
        didChange: ((FetchedRecordsController<Record>) -> Void)? = nil)

    Parameters

    willChange

    Invoked before records are updated.

    onChange

    Invoked for each record that has been added, removed, moved, or updated.

    didChange

    Invoked after records have been updated.

  • Registers changes notification callbacks.

    This method must be used from the controller’s dispatch queue (the main queue unless stated otherwise in the controller’s initializer).

    Declaration

    Swift

    public func trackChanges<T>(
        fetchAlongside: @escaping (Database) throws -> T,
        willChange: ((FetchedRecordsController<Record>, _ fetchedAlongside: T) -> Void)? = nil,
        onChange: ((FetchedRecordsController<Record>, Record, FetchedRecordChange) -> Void)? = nil,
        didChange: ((FetchedRecordsController<Record>, _ fetchedAlongside: T) -> Void)? = nil)

    Parameters

    fetchAlongside

    The value returned from this closure is given to willChange and didChange callbacks, as their fetchedAlongside argument. The closure is guaranteed to see the database in the state it has just after eventual changes to the fetched records have been performed. Use it in order to fetch values that must be consistent with the fetched records.

    willChange

    Invoked before records are updated.

    onChange

    Invoked for each record that has been added, removed, moved, or updated.

    didChange

    Invoked after records have been updated.

  • Registers an error callback.

    Whenever the controller could not look for changes after a transaction has potentially modified the tracked request, this error handler is called.

    The request observation is not stopped, though: future transactions may successfully be handled, and the notified changes will then be based on the last successful fetch.

    This method must be used from the controller’s dispatch queue (the main queue unless stated otherwise in the controller’s initializer).

    Declaration

    Swift

    public func trackErrors(_ errorHandler: @escaping (FetchedRecordsController<Record>, Error) -> Void)
  • Call this method when changes performed while the application is in the background should be processed before the application enters the suspended state.

    Whenever the tracked request is changed, the fetched records controller sets up a background task using UIApplication.beginBackgroundTask(expirationHandler:) which is ended after the didChange callback has completed.

    Declaration

    Swift

    public func allowBackgroundChangesTracking(in application: UIApplication)

Accessing Records

  • The fetched records.

    The value of this property is nil until performFetch() has been called.

    The records reflect the state of the database after the initial call to performFetch, and after each database transaction that affects the results of the fetch request.

    This property must be used from the controller’s dispatch queue (the main queue unless stated otherwise in the controller’s initializer).

    Declaration

    Swift

    public var fetchedRecords: [Record] { get }

Configuration

  • Call this method when changes performed while the application is in the background should be processed before the application enters the suspended state.

    Whenever the tracked request is changed, the fetched records controller sets up a background task using UIApplication.beginBackgroundTask(expirationHandler:) which is ended after the didChange callback has completed.

Accessing Records

  • Returns the object at the given index path.

    Declaration

    Swift

    public func record(at indexPath: IndexPath) -> Record

    Parameters

    indexPath

    An index path in the fetched records.

    If indexPath does not describe a valid index path in the fetched records, a fatal error is raised.

Querying Sections Information

  • The sections for the fetched records.

    You typically use the sections array when implementing UITableViewDataSource methods, such as numberOfSectionsInTableView.

    The sections array is never empty, even when there are no fetched records. In this case, there is a single empty section.

    Declaration

    Swift

    public var sections: [FetchedRecordsSectionInfo<Record>] { get }

Initialization

  • Creates a fetched records controller initialized from a SQL query and its eventual arguments.

    let controller = FetchedRecordsController<Wine>(
        dbQueue,
        sql: "SELECT * FROM wine WHERE color = ? ORDER BY name",
        arguments: [Color.red])
    

    The records are compared by primary key (single-column primary key, compound primary key, or implicit rowid). For a database table which has an id primary key, this initializer is equivalent to:

    // Assuming the wine table has an `id` primary key:
    let controller = FetchedRecordsController<Wine>(
        dbQueue,
        sql: "SELECT * FROM wine WHERE color = ? ORDER BY name",
        arguments: [Color.red],
        isSameRecord: { (wine1, wine2) in wine1.id == wine2.id })
    

    Declaration

    Swift

    public convenience init(
        _ databaseWriter: DatabaseWriter,
        sql: String,
        arguments: StatementArguments = StatementArguments(),
        adapter: RowAdapter? = nil,
        queue: DispatchQueue = .main) throws

    Parameters

    databaseWriter

    A DatabaseWriter (DatabaseQueue, or DatabasePool)

    sql

    An SQL query.

    arguments

    Optional statement arguments.

    adapter

    Optional RowAdapter

    queue

    A serial dispatch queue (defaults to the main queue)

    The fetched records controller tracking callbacks will be notified of changes in this queue. The controller itself must be used from this queue.

  • Creates a fetched records controller initialized from a fetch request from the Query Interface.

    let request = Wine.order(Column("name"))
    let controller = FetchedRecordsController(
        dbQueue,
        request: request)
    

    The records are compared by primary key (single-column primary key, compound primary key, or implicit rowid). For a database table which has an id primary key, this initializer is equivalent to:

    // Assuming the wine table has an `id` primary key:
    let controller = FetchedRecordsController<Wine>(
        dbQueue,
        request: request,
        isSameRecord: { (wine1, wine2) in wine1.id == wine2.id })
    

    Declaration

    Swift

    public convenience init<Request>(
        _ databaseWriter: DatabaseWriter,
        request: Request,
        queue: DispatchQueue = .main) throws
        where Request: FetchRequest, Request.RowDecoder == Record

    Parameters

    databaseWriter

    A DatabaseWriter (DatabaseQueue, or DatabasePool)

    request

    A fetch request.

    queue

    A serial dispatch queue (defaults to the main queue)

    The fetched records controller tracking callbacks will be notified of changes in this queue. The controller itself must be used from this queue.

Available where Record: EncodableRecord

  • Returns the indexPath of a given record.

    Declaration

    Swift

    public func indexPath(for record: Record) -> IndexPath?

    Return Value

    The index path of record in the fetched records, or nil if record could not be found.