Skip to content

Latest commit

 

History

History
271 lines (189 loc) · 7.07 KB

xamarin.md

File metadata and controls

271 lines (189 loc) · 7.07 KB

OctoDB on Xamarin

There are 2 options to use OctoDB on Xamarin:

  • SQLite.NET
  • Microsoft.Data.SQLite

SQLite.NET

The SQLite.NET for OctoDB is a fork of SQLite.NET that uses the OctoDB library

Instructions

First follow the instructions to compile OctoDB for mobile or use the pre-compiled native libraries

You can start downloading the free version:

Add the native libraries to the project according to the platform

Android

On Android you may have a folder structure like this:

- lib
    - arm64-v8a
    - armeabi-v7a
    - x86
    - x86_64

On each sub-folder you may have 4 libraries:

liboctodb.so
libuv.so
libbinn.so
libsecp256k1-vrf.so

For each of the .so files, CONTROL + CLICK then set Build Action to AndroidNativeLibrary

iOS

On iOS we should have 4 fat libraries for static linking:

liboctodb.a
libuv.a
libbinn.a
libsecp256k1-vrf.a

CONTROL + CLICK on the Xamarin.iOS project then choose Add > Add Native Reference and select the 4 libraries from the folder

CONTROL + CLICK on each library, click Properties and enable these items:

√ Force Load
√ Smart Link

Nuget Packages

Install with these commands:

dotnet add package SQLitePCLRaw.core  --version 2.0.4
dotnet add package SQLitePCLRawProvider.static  --version 2.0.4
dotnet add package SQLitePCLRawProvider.OctoDB  --version 2.0.4

Finally

Add the SQLite.cs file to your project

And define the __MOBILE__ and USE_SQLITEPCL_RAW conditional variables in the main/shared project

Tables

The library contains simple attributes that you can use to control the construction of tables

public class TodoItem
{
    [PrimaryKey, AutoIncrement]
    public long ID { get; set; }
    public string Name { get; set; }
    public bool Done { get; set; }
}

On tables with integer primary keys the primary key column must be declared as long instead of int because OctoDB always use a 64-bit number for row ids

Example Code

using SQLite;
using SQLitePCL;

if (Device.RuntimePlatform == Device.iOS)
{
    // use the OctoDB static native library
    SQLitePCL.raw.SetProvider(new SQLite3Provider_static());
}
else // if (Device.RuntimePlatform == Device.Android)
{
    // load the OctoDB dynamic native library
    SQLitePCL.raw.SetProvider(new SQLite3Provider_OctoDB());
}

// open the database
var databasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "App.db");
var uri = "file:" + databasePath + "?node=secondary&connect=tcp://123.45.67.89:1234";
var db = new SQLiteConnection(uri);

// check if the database is ready
if (db.IsReady()) {
    // the user is already logged in. show the main screen
    ...
} else {
    // the user is not logged in. show the login screen (and do not access the database!)
    ...
    // wait until the login is successful
    db.OnReady(() => {
        // the log in was successful. show the main screen (the app can access the database now)
        ...
    });
}

// subscribe to db sync notifications
db.OnSync(() => {
    // update the screen with new data
    ...
});

To retrieve the synchronization status:

var status = db.ExecuteScalar<string>("pragma sync_status");

Microsoft.Data.SQLite

The Microsoft.Data.SQLite uses the SQLitePCLRaw to interface with the native library

Native Library

First follow the instructions to compile OctoDB for mobile or use the pre-compiled native libraries. You can start downloading the free version:

Add the native libraries to the project according to the platform

Android

On Android you may have a folder structure like this:

- lib
    - arm64-v8a
    - armeabi-v7a
    - x86
    - x86_64

On each sub-folder you may have 4 libraries:

liboctodb.so
libuv.so
libbinn.so
libsecp256k1-vrf.so

For each of the .so files, CONTROL + CLICK then set Build Action to AndroidNativeLibrary

iOS

On iOS we should have 4 fat libraries for static linking:

liboctodb.a
libuv.a
libbinn.a
libsecp256k1-vrf.a

CONTROL + CLICK on the Xamarin.iOS project then choose Add > Add Native Reference and select the 4 libraries from the folder

CONTROL + CLICK on each library, click Properties and enable these items:

√ Force Load
√ Smart Link

Nuget Packages

Install with these commands:

dotnet add package Microsoft.Data.Sqlite
dotnet add package Microsoft.Data.Sqlite.Core
dotnet add package SQLitePCLRaw.core  --version 2.0.4
dotnet add package SQLitePCLRawProvider.static  --version 2.0.4
dotnet add package SQLitePCLRawProvider.OctoDB  --version 2.0.4

Example Code

Make sure to load the native library before using Microsoft.Data.Sqlite

Also, avoid using a SQLitePCLRaw bundle package which might override the dynamic provider

using Microsoft.Data.Sqlite;
using SQLitePCL;

namespace OctoDBExample
{
    class Program
    {
        static void Main()
        {

            if (Device.RuntimePlatform == Device.iOS)
            {
                // use the OctoDB static native library
                SQLitePCL.raw.SetProvider(new SQLite3Provider_static());
            }
            else // if (Device.RuntimePlatform == Device.Android)
            {
                // load the OctoDB dynamic native library
                SQLitePCL.raw.SetProvider(new SQLite3Provider_OctoDB());
            }
            SQLitePCL.raw.FreezeProvider(true);

            // open the database
            var uri = "file:test.db?node=primary&bind=tcp://0.0.0.0:1234";
            var db = new SqliteConnection("Data Source=" + uri);
            db.Open();

            // check if the db is ready
            while (true) {
                SqliteCommand cmd = db.CreateCommand();
                cmd.CommandText = "pragma sync_status";
                string status = (string) cmd.ExecuteScalar();
                if (status == null) {
                    Console.WriteLine("the loaded library does not contain OctoDB");
                    return;
                }
                if (status.Contains("\"db_is_ready\": true")) break;
                System.Threading.Thread.Sleep(250);
            }

            // subscribe to db sync notifications
            db.CreateFunction("sync_notification", () => {
                // notification received on the worker thread - you can transfer it to the main thread here
                Console.WriteLine("db sync received");
            });

            // now we can use the database
            ...
        }
    }
}