Migrating from Version 1.x to Version 3

The Xamarin v3 SDK is currently in Early Adopter phase, and as a result, this document will be constantly evolving as we move towards General Availability. Please check back periodically for the latest migration updates.

Version 3 of the Kinvey libraries adds a number of new capabilities, and incorporates feedback from our developers into a powerful, improved API. We've simplified our libraries to enable common use cases such as syncing, offline usage, user management and querying with minimal code for the app developer.

We recommend that all Kinvey apps use the latest version of the library. This guide is intended to help developers who wish to migrate to v3 from an earlier Kinvey library version.

What's New in Version 3

Version 3 is a major overhaul of the Kinvey mobile libraries that improves on the previous versions and adds several new features. Here are some highlights of the new capabilities of v3:

Data Store Types and Sync

Version 3 simplifies the DataStore with built-in caching and syncing capabilities. We have designed our data stores in a way that makes it easy for developers to support different caching and offline use cases. All you need to do is specify a type when a data store is created. The library takes care of configuring read and write policies, creating and managing a cache, keeping track of offline write operations and optimizing data transfers between the device and the backend. Syncing your backend in Version 3 is much easier with the new pull(), push() and sync() APIs on the DataStores.

For more, check out our DataStore guide.

Querying

Queries can be expressed using the native syntax you are familiar with - for example, you can write queries as NSPredicates on iOS or Lync on Xamarin. The library uses the native expressions to query the cache locally, and seamlessly translates the query when it is run against the backend.

For more, check out the section on querying in our DataStore guide.

Delta Set Caching

In Version 3, we designed a mechanism to reduce the amount of data transferred between the app and the backend on a data fetch. We call this mechanism "delta set caching", and we recommend that developers enable it to gain significant performance benefits in data synchronization.

For more, check out our caching and offline guide.

Resumable File Uploads

Version 3 supports resumable file uploads with Google Cloud Storage. The library will try to upload as much of a file as possible and handle interruptions seamlessly by resuming where it left off.

For more, check out our file guide.

Before You Start

Before starting out with the 3.x version of the Kinvey SDK, there are a few broad changes which affect the way you use the SDK, from 1.x to 3.x. Please read this overview to help you get started with your migration.

Awaitable API Methods

In the API for the 1.x SDK, there were a couple of ways to use the API methods. One was to call methods and pass in a KinveyDelegate<T> callback into the function in order to receive the method results. Another method that was added later on was to use the async methods which support Task-based Asynchronous Programming paradigm.

In the 3.x version of the SDK, in order to improve the API as well as encourage good programming practice, we have removed the KinveyDelegate<T> style of API, and instead favor the use of async methods, which are await-able.

v1.x

todoStore.Get(new KinveyDelegate<ToDo[]>() {
    onSuccess = (result) =>
    {
        // handle success
    },
    onError = (error) =>
    {
        // handle error
    }
});

v3.x

List<ToDo> todoList = await todoStore.FindAsync();

Naming conventions

There have been some changes to the naming convention of the API methods in the v3 SDK. For starters, method names, by convention, should all start with a capital letter.

v1.x

Client.Builder builder = new Client.Builder();
Client myClient = builder.build();

v3.x

Client.Builder builder = new Client.Builder();
Client myClient = await builder.Build();

It is also convention to have Async as a suffix for any API method that is an async method that is await-able.

Initializing Kinvey

Building the Kinvey Client

With v3, building the Client is now an awaitable task. In v1, the Client.Builder.build() method was not asynchronous, and so build() could be called direcly on a new Client.Builder object. Now in v3, since the building of a Client object could involve the asynchronous process of logging in a user saved in the credential store, Build() is an async method:

v1.x

Client kinveyClient = new Client.Builder(your_app_key, your_app_secret)
            .setLogger(delegate(string msg) { Console.WriteLine(msg);})
            .setFilePath(NSFileManager.DefaultManager.GetUrls (NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User) [0].ToString())
            .setOfflinePlatform(new SQLitePlatformIOS())
            .build();

v3.x

Client.Builder builder = new Client.Builder(your_app_key, your_app_secret)
            .setLogger(delegate(string msg) { Console.WriteLine(msg); })
            .setFilePath(NSFileManager.DefaultManager.GetUrls (NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomain.User) [0].ToString())
            .setOfflinePlatform(new SQLitePlatformIOS());

Client kinveyClient = await builder.Build();

Shared Client

In v1, when you built a client, you would save the Client object returned from the Client.Builder.build() method. Now in v3, there is the concept of SharedClient, which is a static variable that is available on the Client class, which will automatically be set to the result of the Client.Builder.Build() method. This allows you to use the SDK without explicitly passing in the Client object into APIs.

v1.x

AsyncAppData<ToDo> todoStore = kinveyClient.AppData<ToDo>("todoCollection",typeof(ToDo));

v3.x

DataStore<ToDo> todoStore = DataStore<ToDo>.Collection("todoCollection");

Refer to the Getting Started guide for details.

Data Store

In v1, data stores were accessed by type using the AsyncAppData<T> class, either via the AppData<T> constructor or via the getInstance() method. In v3, the class that handles data store operations is now simply called DataStore<T>, and in order to access a data store for a particular collection, the static DataStore<T>.Collection() method is called.

v1.x

AsyncAppData<ToDo> todoStore = kinveyClient.AppData<ToDo>("todoCollection",typeof(ToDo));

v3.x

DataStore<ToDo> todoStore = DataStore<ToDo>.Collection("todoCollection");

Fetching

With fetching entities, there are two primary changes. First, fetching methods no longer returns an array of those entities, but instead will return a List of those entities. And secondly, the names of the fetch methods are now Find instead of Get.

v1.x

ToDo[] todoEntities = await todoStore.GetAsync();

v3.x

List<ToDo> todoList = await todoStore.FindAsync();

Saving

Outside of the larger DataStore changes, the save API is similar to its 1.x counterpart.

v1.x

ToDo todoItem = new ToDo();
todoItem = await todoStore.SaveAsync(todoItem);

v3.x

ToDo todoItem = new ToDo();
todoItem = await todoStore.SaveAsync(todoItem);

Deleting

The main change in the delete API is the name of the delete method has changed from DeleteAsync to RemoveAsync.

v1.x

KinveyDeleteResponse kdr = await todoStore.DeleteAsync(todoItem.ID);

v3.x

KinveyDeleteResponse kdr = await todoStore.RemoveAsync(todoItem.ID);

Caching, Offline and Sync

Offline storage and caching was offered in v1 of the SDK; however, the underpinning of how data is stored has changed in v3 in order to support the different types of DataStoreTypes that are available. In order to support this in v3, a new model class called Entity has been introduced, from which all data store model classes should inherit.

v1.x

[JsonObject(MemberSerialization.OptIn)]
public class ToDo
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty ("details")]
    public string Details { get; set; }

    [JsonProperty("due_date")]
    public string DueDate { get; set; }
}

v3.x

[JsonObject(MemberSerialization.OptIn)]
public class ToDo : Entity
{
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty ("details")]
    public string Details { get; set; }

    [JsonProperty("due_date")]
    public string DueDate { get; set; }
}

Refer to the Data Store guide for details.

Relational Data

Previous major versions of the library include KinveyRefs - a feature for modeling and automatically handling relationships between data entities. This is a useful tool, but suffers from several limitations, such as the limit on number of references, performance during data retrieval etc.

The recommended way to handle data relationships in 3.x is described in Data Modeling guide. The v3 libraries do not implement KinveyRefs, but an equivalent capability of automatically handling relationships is on our roadmap.

Users

Active User

In v1, the user that is currently logged into the app, called the active user, is accessed by calling the User() method on the Client object. In v3, the active user is now accessed by a property on the Client called ActiveUser. This is called to get the user that is logged into the app.

v1.x

User v1User = kinveyClient.User();

v3.x

User v3User = kinveyClient.ActiveUser;

Static User Methods

In v1, the methods of operation available on a user were instance methods, accessed through the current user. In a lot of cases, it made more sense from an API perspective to place these methods on the User class. These methods, such as SignupAsync and LoginAsync, do not require an active user, since these methods will return the active user object, and so they are now available as a static method on the User class.

v1.x

User activeUser = await kinveyClient.User().LoginAsync();

v3.x

User activeUser = await User.LoginAsync();

User Creation Method

The main change in the user creation API is the name of the method has changed from CreateAsync to SignupAsync.

v1.x

User newUser = await kinveyClient.User().CreateAsync(username, password);

v3.x

User newUser = await User.SignupAsync(username, password);

Refer to the Users guide for details.

Files

As with other APIs in the v3 SDK, the File API only has awaitable methods, since the KinveyDelegate<T> versions of the File methods have been removed.

v1.x

kinveyClient.File().download(meta, file, new KinveyDelegate<FileMetaData>() {
  onSuccess = (metadata) => {
    // downloaded, `metadata` is FileMetaData associated with the file.
  },
  onError = (error) => {
    // `error` contains information about the error that occured.
  }
});

v3.x

FileMetaData downloadFMD = await kinveyClient.File().downloadAsync(downloadMetaData, downloadContent);

Get Started

For more information take a look at the all of our DevCenter Guides. If you have any issues or need help, please reach out to us using Kinvey Support. To get started developing great apps, take a look at our Getting Started Guide.

Got a question?