Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

An asynchronous, persistent key-value store created for writing desktop and mobile applications, based on SQLite3. Akavache is great for both storing important data as well as cached local data that expires.

License

NotificationsYou must be signed in to change notification settings

reactiveui/Akavache

Repository files navigation

NuGet StatsBuildCode Coverage

Akavache

Akavache: An Asynchronous Key-Value Store for Native Applications

Akavache is anasynchronous,persistent (i.e. writes to disk) key-valuestore created for writing desktop and mobile applications in C#, based onSQLite3. Akavache is great for both storing important data (i.e. usersettings) as well as cached local data that expires.

Where can I use it?

Akavache is currently compatible with:

  • Xamarin.iOS / Xamarin.Mac / Xamarin.Android / Xamarin.TVOS / Xamarin.WatchOS
  • Maui iOS / Mac / Mac Catalyst / Android / TVOS
  • .NET 4.6.2 (and above) and .NET 6 Desktop (WPF and WinForms)
  • .NET 6.0
  • Windows 10 (Universal Windows Platform)
  • Tizen 4.0

What does that mean?

Downloading and storing remote data from the internet while still keeping theUI responsive is a task that nearly every modern application needs to do.However, many applications that don't take the consideration of caching intothe design from the start often end up with inconsistent, duplicated code forcaching different types of objects.

Akavache is a library that makes common apppatterns easy, and unifies caching of different object types (i.e. HTTPresponses vs. JSON objects vs. images).

It's built on a core key-value byte array store (conceptually similar to aDictionary<string, byte[]>), and on top of that store, extensions areadded to support:

  • Arbitrary objects via JSON.NET
  • Fetching and loading Images and URLs from the Internet
  • Storing and automatically encrypting User Credentials

Contents

Getting Started

Interacting with Akavache is primarily done through an object calledBlobCache. At App startup, you must first set your app's name viaBlobCache.ApplicationName orAkavache.Registrations.Start("ApplicationName") . After setting your app's name, you're ready to save some data.

For example with Xamarin Forms or WPF applications you'll place this in the constructor of yourApp.xaml.cs file.

Choose a location

There are four built-in locations that have some magic applied on some systems:

  • BlobCache.LocalMachine - Cached data. This data may get deleted without notification.
  • BlobCache.UserAccount - User settings. Some systems backup this data to the cloud.
  • BlobCache.Secure - For saving sensitive data - like credentials.
  • BlobCache.InMemory - A database, kept in memory. The data is stored for the lifetime of the app.

The magic

  • Xamarin.iOS may remove data, stored inBlobCache.LocalMachine, to free up disk space (only if your app is not running). The locationsBlobCache.UserAccount andBlobCache.Secure will be backed up to iCloud and iTunes.Apple Documentation
  • Xamarin.Android may also start deleting data, stored inBlobCache.LocalMachine, if the system runs out of disk space. It isn't clearly specified if your app could be running while the system is cleaning this up.Android Documentation
  • Windows 10 (UWP) will replicateBlobCache.UserAccount andBlobCache.Secure to the cloud and synchronize it to all user devices on which the app is installedUWP Documentation

Platform-specific notes

  • Windows 10 (Universal Windows Platform) - You must mark your application asx86orARM, or else you will get a strange runtime error about SQLitePCL_Raw notloading correctly. You mustalso ensure that the Microsoft Visual C++ runtimeis added to your project.

Handling Xamarin/Maui Linker

There are two options to ensure the Akavache.Sqlite3 dll will not be removed by Xamarin and Maui build tools

1) Add a file to reference the types

publicstaticclassLinkerPreserve{staticLinkerPreserve(){varpersistentName=typeof(SQLitePersistentBlobCache).FullName;varencryptedName=typeof(SQLiteEncryptedBlobCache).FullName;}}

2) Use the following initializer in your cross platform library or in your head project

Akavache.Registrations.Start("ApplicationName")

Using Akavache

The most straightforward way to use Akavache is via the object extensions:

usingSystem.Reactive.Linq;// IMPORTANT - this makes await work!// Make sure you set the application name before doing any inserts or getsAkavache.Registrations.Start("AkavacheExperiment")varmyToaster=newToaster();awaitBlobCache.UserAccount.InsertObject("toaster",myToaster);//// ...later, in another part of town...//// Using async/awaitvartoaster=awaitBlobCache.UserAccount.GetObject<Toaster>("toaster");// or without async/awaitToastertoaster;BlobCache.UserAccount.GetObject<Toaster>("toaster").Subscribe(x=>toaster=x, ex=>Console.WriteLine("No Key!"));

Handling Errors

When a key is not present in the cache, GetObject throws aKeyNotFoundException (or more correctly, OnError's the IObservable). Often,you would want to return a default value instead of failing:

Toastertoaster;try{toaster=awaitBlobCache.UserAccount.GetObject("toaster");}catch(KeyNotFoundExceptionex){toaster=newToaster();}// Or without async/await:toaster=awaitBlobCache.UserAccount.GetObject<Toaster>("toaster").Catch(Observable.Return(newToaster()));

Shutting Down

Critical to the integrity of your Akavache cache is theBlobCache.Shutdown() method. Youmust call this when your application shuts down. Moreover, be sure to wait for the result:

BlobCache.Shutdown().Wait();

Failure to do this may mean that queued items are not flushed to the cache.

Using a different SQLitePCL.raw bundle

To use a different SQLitePCL.raw bundle, e.g. Microsoft.AppCenter:

  • Install theakavache.sqlite3 nuget instead ofakavache
  • Install the SQLitePCLRaw bundle you want to use, e.g.,SQLitePCLRaw.bundle_green
  • UseAkavache.Sqlite3.Registrations.Start("ApplicationName", () => SQLitePCL.Batteries_V2.Init()); in your platform projects or in your cross platform project.
<PackageReferenceInclude="akavache.sqlite3"Version="6.0.40-g7e90c572c6" /><PackageReferenceInclude="SQLitePCLRaw.bundle_green"Version="1.1.11" />
Akavache.Sqlite3.Registrations.Start("ApplicationName",()=>SQLitePCL.Batteries_V2.Init());

For more info about using your own versions ofSqlitePCL.raw

Examining Akavache caches

UsingAkavache Explorer, youcan dig into Akavache repos for debugging purposes to see what has been stored.

What's this Global Variable nonsense?

Why can't I use $FAVORITE_IOC_LIBRARY?

You totally can. Just instantiateSQLitePersistentBlobCache orSQLiteEncryptedBlobCache instead - the static variables are there just to make iteasier to get started.

DateTime/DateTimeOffset Considerations

Our default implementation overrides BSON to read and write DateTime's as UTC.To override the reader's behavior you can setBlobCache.ForcedDateTimeKind as in the following example:

// Sets the reader to return DateTime/DateTimeOffset in Local.BlobCache.ForcedDateTimeKind=DateTimeKind.Local;

DateTime are stored as ticks for high precision.DateTimeOffset are stored as ticks for both the Date/Time aspect and the offset.

Basic Method Documentation

Every blob cache supports the basic raw operations given below (some of them arenot implemented directly, but are added on via extension methods):

/* * Get items from the store */// Get a single itemIObservable<byte[]>Get(stringkey);// Get a list of itemsIObservable<IDictionary<string,byte[]>>Get(IEnumerable<string>keys);// Get an object serialized via InsertObjectIObservable<T>GetObject<T>(stringkey);// Get all objects of type TIObservable<IEnumerable<T>>GetAllObjects<T>();// Get a list of objects given a list of keysIObservable<IDictionary<string,T>>GetObjects<T>(IEnumerable<string>keys);/* * Save items to the store */// Insert a single itemIObservable<Unit>Insert(stringkey,byte[]data,DateTimeOffset?absoluteExpiration=null);// Insert a set of itemsIObservable<Unit>Insert(IDictionary<string,byte[]>keyValuePairs,DateTimeOffset?absoluteExpiration=null);// Insert a single objectIObservable<Unit>InsertObject<T>(stringkey,Tvalue,DateTimeOffset?absoluteExpiration=null);// Insert a group of objectsIObservable<Unit>InsertObjects<T>(IDictionary<string,T>keyValuePairs,DateTimeOffset?absoluteExpiration=null);/* * Remove items from the store */// Delete a single itemIObservable<Unit>Invalidate(stringkey);// Delete a list of itemsIObservable<Unit>Invalidate(IEnumerable<string>keys);// Delete a single object (do *not* use Invalidate for items inserted with InsertObject!)IObservable<Unit>InvalidateObject<T>(stringkey);// Deletes a list of objectsIObservable<Unit>InvalidateObjects<T>(IEnumerable<string>keys);// Deletes all items (regardless if they are objects or not)IObservable<Unit>InvalidateAll();// Deletes all objects of type TIObservable<Unit>InvalidateAllObjects<T>();/* * Get Metadata about items */// Return a list of all keys. Use for debugging purposes only.IObservable<IEnumerable<string>>GetAllKeys();// Return the time which an item was createdIObservable<DateTimeOffset?>GetCreatedAt(stringkey);// Return the time which an object of type T was createdIObservable<DateTimeOffset?>GetObjectCreatedAt<T>(stringkey);// Return the time which a list of keys were createdIObservable<IDictionary<string,DateTimeOffset?>>GetCreatedAt(IEnumerable<string>keys);/* * Utility methods */// Attempt to ensure all outstanding operations are written to diskIObservable<Unit>Flush();// Preemptively drop all expired keys and run SQLite's VACUUM method on the// underlying databaseIObservable<Unit>Vacuum();

Extension Method Documentation

On top of everyIBlobCache object, there are extension methods that help withcommon application scenarios:

/* * Username / Login Methods (only available on ISecureBlobCache) */// Save login information for the given hostIObservable<Unit>SaveLogin(stringuser,stringpassword,stringhost="default",DateTimeOffset?absoluteExpiration=null);// Load information for the given hostIObservable<LoginInfo>GetLoginAsync(stringhost="default");// Erase information for the given hostIObservable<Unit>EraseLogin(stringhost="default");/* * Downloading and caching URLs and Images */// Download a file as a byte arrayIObservable<byte[]>DownloadUrl(stringurl,IDictionary<string,string>headers=null,boolfetchAlways=false,DateTimeOffset?absoluteExpiration=null);// Load a given key as an imageIObservable<IBitmap>LoadImage(stringkey,float?desiredWidth=null,float?desiredHeight=null);// Download an image from the network and load itIObservable<IBitmap>LoadImageFromUrl(stringurl,boolfetchAlways=false,float?desiredWidth=null,float?desiredHeight=null,DateTimeOffset?absoluteExpiration=null);/* * Composite operations */// Attempt to return an object from the cache. If the item doesn't// exist or returns an error, call a Func to return the latest// version of an object and insert the result in the cache.IObservable<T>GetOrFetchObject<T>(stringkey,Func<Task<T>>fetchFunc,DateTimeOffset?absoluteExpiration=null);// Like GetOrFetchObject, but isn't asyncIObservable<T>GetOrCreateObject<T>(stringkey,Func<T>fetchFunc,DateTimeOffset?absoluteExpiration=null);// Immediately return a cached version of an object if available, but *always*// also execute fetchFunc to retrieve the latest version of an object.IObservable<T>GetAndFetchLatest<T>(thisIBlobCacheThis,stringkey,Func<IObservable<T>>fetchFunc,Func<DateTimeOffset,bool>fetchPredicate=null,DateTimeOffset?absoluteExpiration=null,boolshouldInvalidateOnError=false,Func<T,bool>cacheValidationPredicate=null)

About

An asynchronous, persistent key-value store created for writing desktop and mobile applications, based on SQLite3. Akavache is great for both storing important data as well as cached local data that expires.

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Sponsor this project

 

Languages


[8]ページ先頭

©2009-2025 Movatter.jp