Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalized “TableViewEvent” for both platforms & more views #160

Merged
merged 1 commit into from
Jan 4, 2017

Conversation

kdubb
Copy link
Contributor

@kdubb kdubb commented Dec 30, 2016

There is nothing specific to UITableView in the implementation of TableViewEvent features. The events are useful to users of UICollectionView also. Finally, as of macOS 10.10, both view types are now supported on macOS. For all these reasons TableViewEvent features were migrated to support both platforms & renamed not to confuse end users who might be thinking they're only for table views.

  • TableViewEvent features of FetchedRecordsController supported on both platforms
  • Renamed TableViewEvent to FetchedRecordsChangeEvent
  • Renamed TableViewChange to FetchedRecordsChange

* TableViewEvent features of FetchedRecordsController supported on all platforms
* Renamed TableViewEvent to FetchedRecordsChangeEvent
* Renamed TableViewChange to FetchedRecordsChange
@kdubb
Copy link
Contributor Author

kdubb commented Dec 30, 2016

Other notes:

  • FetchedRecordsControlleriOSTests.swift was merged with FetchedRecordsControllerTests.swift
  • All tests pass for iOS & OS X targets

@groue
Copy link
Owner

groue commented Dec 30, 2016

Hello @kdubb!

Wow, thanks for this PR.

Yes, I overlooked both macOS 10.10 additions, and the fact that collection views are compatible with table views regarding the insertion/deletion/moving of cells: there is no need to restrict those APIs to iOS, and there is no need to use TableView in the API names.

Now it happens that your work overlaps an on-going refactoring process that happens in the RX branch, so I wonder if I should merge your PR, or combine our ideas together in RX, until it lands in master.

In RX, I'm trying to achieve two main goals:

  • Lift the restriction of FetchedRecordsController on records. I'd like any fetchable type to be tracked (records, but also values, and raw rows for consistency's sake). It has happened a couple of times that I define an ad-hoc record just for tracking values, and this obscures the application code more than I wish it would. I wish tracking simple value requests were possible.

  • Exhibit low-level request tracking components that can be bound to Reactive libraries. Exposing a reactive toolkit would allow several features unavailable to FetchedRecordsController, that all turn around the control of when view updates happen. For example:

    • changes throttling (when you perform frequent database updates - a request from @hdlj)
    • delayed view updates (when you want the changes to animate a view long after the changes were actually performed in the database)

In the process, a few other sub-goals have emerged:

  • Since tracking is no longer reserved to records requests, but also any fetchable types, the FetchedRecordsController name is no longer valid, just as its fetchedRecords property name.

    In the current state of the refactoring, FetchedRecordsController has been renamed FetchedCollection (maybe FetchedArray would be better), and it implements the Collection protocol:

    let request = Player.order(Column("score"))
    
    // Old
    let playersController = try FetchedRecordsController<Player>(dbQueue, request: request)
    playersController.trackChanges    (
        recordsWillChange: { controller in ... },
        tableViewEvent: { (controller, record, event) in ... },
        recordsDidChange: { controller in ... })
    try playersController.performFetch()
    playersController.fetchedRecords?.first // Player?
    
    // New
    let players = try FetchedCollection(dbQueue, request: request)
    players.trackChanges(
        willChange: { collection in ... },
        onChange: { (collection, player, change) in ... },
        didChange: { collection in ... })
    try players.fetch()
    players.first // Player?

    You see, I've already removed "tableView" from the API :-)

    Also, the TypedRequest protocol introduced in v0.95.0 allows FetchedCollection to infer its fetched type automatically.

    An open question is: since the new tracking type is a collection, it now naturally belongs the the model realm, and no longer in the controller realm: playersController is now simply players. I really don't know if it is a good idea or not.

  • Automatic primary key identification

    Currently FetchedRecordsController requires the user to explicitly declare how records are compared, so that update events can be emitted. Very frequently, it is on the primary key. With types that adopt both RowConvertible and TableMapping, such as Record subclasses, you can use the compareRecordsByPrimaryKey argument:

    let controller = try FetchedRecordsController<Player>(
        dbQueue,
        request: request,
        compareRecordsByPrimaryKey: true)

    It happens that this can be achieved automatically:

    // Records are compared by primary key by default
    let players = try FetchedCollection(dbQueue, request: request)

That's the current state of affairs.

What do you think?

@kdubb
Copy link
Contributor Author

kdubb commented Dec 30, 2016

@groue

I think I like most of these changes, although I'll need to experiment with the actual implementations to make sure they were fine for use (first glance all seems well).

As for timing... I'd love to see this PR merged (since it's fairly simple). It's only effect on most end users would be renaming tableViewEvent -> event in calls to trackChanges. You seem to be tackling a few issues in the RX branch outside this and it would be nice to have proper, general, support for "events" while these changes are worked through.


Some thoughts on naming in RX... FetchedXXX this naming is a holdover from the fact it's a "work-alike" to NSFetchedResultsController; that nomenclature actually means very little to me. Now that you're straying further away (in name) I'd suggest something with the following:

    • Live: (e.g. LiveQuery or LiveRequest) with fetch moving to enable
    • Active: (e.g. ActiveQuery or ActiveRequest) with fetch moving to activate
    • Listener: (e.g. QueryListener or RequestListener) with fetch moving to listen
    • Tracker: (e.g. QueryTracker or RequestTracker) with fetch moving to track

@groue
Copy link
Owner

groue commented Dec 30, 2016

As for timing... I'd love to see this PR merged.

I'm inclined on this side as well. New Year's Eve is coming so I guess we'll have to wait a little bit nevertheless.

Some thoughts on naming in RX... FetchedXXX this naming is a holdover from the fact it's a "work-alike" to NSFetchedResultsController; that nomenclature actually means very little to me.

You're right. NSFetchedResultsController has been a tremendous inspiration. Eventual diverging is natural, but also questioning. For example, you're developing on macOS, which uses bindings, NSArrayController, et al. I suppose that NSFetchedResultsController was a perfect fit for the macOS platform. Nowadays new patterns are emerging, but throwing the baby out with the bathwater could be stupid.

That's why I think the RX branch will take a while to complete, and I'm seriously considering merging your PR before. Give me a few days – no new development will happen in GRDB, and your fork will remain ahead of master.

@swiftlyfalling
Copy link
Collaborator

swiftlyfalling commented Dec 31, 2016

I made a private fork with very similar changes for a side-project (did not have a chance to package them up nicely for a PR), so I'm 100% in support of this change. 👍

@groue groue merged commit f368af3 into groue:master Jan 4, 2017
groue added a commit that referenced this pull request Jan 4, 2017
@groue
Copy link
Owner

groue commented Jan 4, 2017

Welcome @kdubb to the GRDB contributors! v0.100.0 (a nice version number) will ship after FetchedRecordsController outdated documentation has been updated.

groue added a commit that referenced this pull request Jan 10, 2017
@groue
Copy link
Owner

groue commented Jan 10, 2017

Here we go: v0.100.0 is out.

@kdubb I took the liberty to introduce a couple other modifications on FetchedRecordsController.

And custom SQLite has been bumped to 3.16.2, thanks to @swiftlyfalling's SQLiteLib.

@groue groue mentioned this pull request Aug 24, 2019
13 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants