`IScrobbler` provides an interface for scrobbler classes. The `Inflatable.Lastfm` package comes with a basic scrobbler that does not support caching; to get caching you can use the SQLiteScrobbler provided in `Inflatable.Lastfm.SQLite` package, or you can [integrate your own database](#extensibility).
There must be at least 30 seconds in between each scrobble. This means you may scrobble at most `(24 * 60 * 60) / 30 = 2880` tracks in one day. If this limit is reached then the scrobbles will be cached if it's enabled.
As currently implemented, Scrobblers will only scrobble when the `ScrobbleAsync()` method is called. Any cached scrobbles will be sent then, and only then. As an illustration, this is a scenario involving our friendly test-subject, User:
- When track2 finishes, User now has a network connection. The call to `scrobbler.ScrobbleAsync()` inspects its cache, and ends up sending both track1 and track2.
- User is content in the presence of accurate statistics.
- User's train enters another tunnel.
- Track3 finishes playing, but User has no network connection. The scrobble for track3 is cached for later.
- Since the User's playlist has ended, they duly unplug their headphones and exit the train.
At this point, track1 and track2 have been scrobbled - but track3 has not! Track3 is in the scrobble cache. It is not until User's commute, back to their residence in Townsville, when they listen to track4. Only when track4 is finished playing will track3 be scrobbled.
Solving this problem requires some sort of background task to empty the cache. You can write your own that calls `scrobbler.SendCachedScrobblesAsync()`.
Last.fm do not accept scrobbles which are older than two weeks (UTC). There's no point sending them, so Scrobbles passed to `ScrobbleAsync()` which are older than two weeks will be silently dropped.
The `ScrobblerBase` class may be extended in your own project to integrate with the database that suits you best. The derived class needs to implement `GetCachedScrobblesAsync()`, which should return an `IEnumerable<Scrobble>`, and `CacheAsync(Scrobble s)` which should return `LastResponseStatus.Cached` if successful or throw an exception if not. Exceptions thrown in `CacheAsync()` will be caught and returned to the user as error codes (see: #5).
To use the SQLiteScrobbler, install [Inflatable.Lastfm.SQLite]() from NuGet. This package will be updated according to major versions of sqlite-net-pcl.