v8 -> v9 Migration

v9 is a complete rewrite of FMTC internals, written over hundreds of hours. It focuses on:

  • improved future maintainability by modularity

  • improved stability & performance across the board

  • support of 'tiles across stores': reduced duplication

Check out the CHANGELOG: https://pub.dev/packages/flutter_map_tile_caching/changelog! This page only covers breaking changes, not feature additions and fixes.

These migration instructions will not cover every scenario, because the number of breaking changes is so high. I've done my best to organise them into categories.


Stores and roots from previous versions will be incompatible with v9, and will not be migratable.

This is because the underlying storage technology has chnaged from Isar to ObjectBox (in the default instance, at least).

Therefore, before publishing a version of your app with v9, it may be beneficial to notify users of the upcoming change, so the sudden dissappearance of their cached data is not unexpected.

Removal of the old cache will need to be performed manually.

Removed the FlutterMapTileCaching/FMTC object, in favour of direct usage of FMTCStore and FMTCRoot (which replace StoreDirectory & RootDirectory)

Much of the configuration and state management performed by the FlutterMapTileCaching top-level object singleton, and it's close relatives, were transferred to the backend, and as such, there is no longer a requirement for these objects.

Additionally, the name 'directory' has been outdated for a while. Therefore, these changes were merged into one.

To migrate, follow these patterns:

// Get a store directory
final StoreDirectory oldStore = FlutterMapTileCaching.instance('storeName'); // (or `FMTC.`)

// Access the root statistics
final RootDirectory oldRoot = FlutterMapTileCaching.instance.rootDirectory; // (or `FMTC.`)
final RootStats oldRootStats = oldRoot.stats;
// Get a store
final FMTCStore newStore = FMTCStore('storeName');

// Access the root statistics
final RootStats newRootStats = FMTCRoot.stats;
// `FMTCRoot` must now be used immediately, because it is not an object instance

See below for information about migrating initialisation.

Changed the method of initialisation & error handling

Due to the removal of the FMTC object, and introduction of multiple-backend support, initialisation is now performed directly on a backend. The backend then creates a link between itself and its implementation to the abstracted convienience methods and front.

Additionally, error handling has been improved throughout FMTC, and is now more consitent and stable, doesn't rely on callbacks, and error StackTraces include more useful information.

For the default, built-in backend, migration is simple:

await FlutterMapTileCaching.initialise(
    errorHandler: (FMTCInitialisationException e) {},
try {
    await FMTCObjectBoxBackend().initialise();
} catch (error, stackTrace) {
    // Improved error handling

For more information, see Initialisation & Error Handling.

Removed support for synchronous operations (and renamed asynchronous operations to reflect this)

These were incompatible with the new Isolated FMTCObjectBoxBackend, they've been removed, in favour of backends implementing their own Isolateion as well.

There is no direct migration instructions, as the correct new solution is case-dependent. In non-widget environments, use asynchronous techniques. In widget builds, make use of FutureBuilders. However, the members have all been renamed in the same form: *Async is now just *.

Bulk Downloading

Refactored DownloadableRegion & removed RegionType

DownloadableRegion no longer contains the outline points of the BaseRegion it was formed from. It also no longer contains parallelThreads, preventRedownload, and seaTileRemoval: these are now configurable at download-time. errorHandler has been removed altogether.

Additionally, DownloadableRegion now makes use of sealed typing by using the type argument to contain the type of BaseRegion, so RegionType has become redundant and been removed.


Background downloading plugin deprecated without replacement

'package:fmtc_plus_background_downloading' has been deprecated without replacment.

It was becoming increasing unstable, and depended on unmaintained, unstable, and small packages. It also only supported Android, and did not properly work in many cases.

Therefore, the plugin has been deprecated without replacement. The functionality may be re-introduced into the core at a later point.

Sharing plugin deprecated, external replacement functionality introduced into core

'package:fmtc_plus_sharing' has been deprecated, and the importing/exporting functionality introduced into the core, as Introduction.

There is no replacement for the GUI/file picker functionality, to keep core dependencies minimized.


RootStats & StoreStats members are no longer prefixed with 'root' & 'store'/'cache'

These terms were redundant, and have been removed.

For example, rootSize is now just size, and cacheHits is now just hits.

Replaced RootStats.watchChanges with watchStores & watchRecovery

watchStores now watches for changes in statistics (which should change whenever tiles are changed), and changes in metadata in the specified stores. watchRecovery is now used to watch for changes to the recovery system.

This was done to simplify the APIs and allow for the removal of StoreParts (which has been removed without deprecation).


Removed FMTCSettings

FMTCSettings have been split apart. databaseMaxSize now has an equivalent in the configuration of the FMTCObjectBoxBackend, databaseCompactCondition has been removed without replacement, and defaultTileProviderSettings has been removed in favour of a singleton-ish FMTCTileProviderSettings.

FMTCTileProviderSettings may now be set as a global instance (which works the same as the old FMTCSettings option) just by constructing it. Alternatively, one can be constructed without setting the global instance by setting setInstance false in the arguments.

Last updated

© Luka Stillingfleet (JaffaKetchup)