Migrating from Version 1.x to Version 2.x

Friday, March 8, 2013

Introduction

Kinvey released an updated Android library v2. We compiled your feedback over the last year and built v2 for much improved data support, including entity caching and offline storage for app developers.

We recommend that all existing Android app developers migrate to v2 to take advantage of the new features and powerful new persistence.

New developers can Get started with v2.x now.

What's New in Version 2

The Kinvey Android library v2.x introduces a new API experience designed for app developers, powerful new data features, and much more. Here's a look at what you get with v2.x:

Relational Data

Using KinveyReference allows an app to store only one authoritative copy of an entity and link to this entity from other entities. It also eliminates the need to issue separate retrieval requests for the linked entities.

Data Aggregation

Aggregate over your collections using five funtions: count, sum, min, max and average.

Compound Querying

With the new querying interface not only can you perform geo-location queris but you can also construct compound querying.

Caching

All data requests including queries and aggregation can optionally be configured to utilize an in-memory LRU cache.

New Social Login

We've added Twitter and LinkedIn

Migrating KCSClient Initialization

v1.x
KinveySettings settings = new KinveySettings("your_app_key", "your_app_secret");
KCSClient mKinveyClient = KCSClient.getInstance(this.getApplicationContext(), settings);
v2.x
Client mKinveyClient = new Client.Builder(
  your_app_key, 
  your_app_secret, 
  this.getApplicationContext()).build();

Handling of Implicit Users

In v1, an implicit user was created and logged in under the hood, in the very first request to Kinvey. In order to clear up confusion with v1 we have made this a required step in v2. For v2 you must call mKinvey.client().login() or mKinvey.client().login(callback).

v1.x
KinveySettings settings = new KinveySettings("your_app_key", "your_app_secret");
KCSClient mKinveyClient = KCSClient.getInstance(this.getApplicationContext(), settings);
mKinveyClient.ping(event, new ScalarCallback<Boolean>() {
  @Override
  public void onFailure(Throwable e) {
    Log.e(TAG, "failed to save event data", e) 
  }

  @Override
  public void onSuccess(Boolean r) {
    Log.d(TAG, "saved data for entity "+ r.getName()); 
  }
});

The above code resulted in an implicit user being created. To achieve the same result in v2

v2.x
final Client mKinveyClient = new Client.Builder(
  your_app_key, 
  your_app_secret, 
  this.getApplicationContext()).build();

mKinveyClient.user().login(new KinveyUserCallback() {

  @Override
  public void onFailure(Throwable error) {
    Log.e(TAG, "Login Failure", error);
  }

  @Override
  public void onSuccess(User result) {
    Log.i(TAG,"Logged in successfully as " + result.getId());
    mKinveyClient.ping(new KinveyPingCallback() {

      public void onFailure(Throwable t) {
        Log.e(TAG, "Kinvey Ping Failed", t);
      }

      public void onSuccess(Boolean b) {
        Log.d(TAG, "Kinvey Ping Success");
      }
    });

  }

});

Line 6 is required in v2.

Migrating MappedAppdata Requests

Migrate MappedEntity Classes

The new library requires that every class implementing MappedEntity now extend the GenericJson instead.

v1.x
public class EventEntity implements MappedEntity {

    private String id; // Kinvey entity _id, REQUIRED
    private String name;
    private String location;
    private String date;
    private KinveyMetadata meta; // Kinvey metadata, OPTIONAL

    @Override
    public List<MappedField> getMapping() {
        return Arrays.asList(new MappedField[] {
            new MappedField("id", "_id") // example where name differs
            , new MappedField("name", "name")
            , new MappedField("location", "location")
            , new MappedField("date", "date")
            , new MappedField("meta", KinveyMetadata.ENTITY_KEY) 
            });
    }

    //REQUIRED: implement getters and setters per Bean conventions

}
v2.x
public class EventEntity extends GenericJson {

    @Key("_id")
    private String id; 
    @Key
    private String name;
    @Key
    private String location;
    @Key
    private String date;

    @Key(KinveyMetaData.JSON_FIELD_NAME)
    private KinveyMetaData meta; // Kinvey metadata, OPTIONAL

    @Key(KinveyMetaData.AccessControlList.JSON_FIELD_NAME)
    private KinveyMetaData.AccessControlList acl; // Kinvey access control, OPTIONAL

}

Update Appdata Methods and Callbacks

v1.x
EventEntity event = new EventEntity();
event.setName("Launch Party");
event.setAddress("Kinvey HQ");
MappedAppdata myevents = mKinveyClient.mappeddata(EventEntity.class, "events");
myevents.save(event, new ScalarCallback<EventEntity>() {
  @Override
  public void onFailure(Throwable e) {
      Log.e(TAG, "failed to save event data", e) 
  }

  @Override
  public void onSuccess(EventEntity r) {
      Log.d(TAG, "saved data for entity "+ r.getName()); 
  }
});
v2.x
EventEntity event = new EventEntity();
event.setName("Launch Party");
event.setAddress("Kinvey HQ");
AsyncAppData<EventEntity> myevents = mKinveyClient.appData("events", EventEntity.class);
myevents.save(event, new KinveyClientCallback<EventEntity>() {
  @Override
  public void onFailure(Throwable e) {
      Log.e(TAG, "failed to save event data", e) 
  }

  @Override
  public void onSuccess(EventEntity r) {
      Log.d(TAG, "saved data for entity "+ r.getName()); 
  }
});

Overview

Client

v1v2
com.kinvey.KCSClientcom.kinvey.android.Client
KCSClient.mappeddataClient.appData
KCSClient.resourceClient.file

Data Store

v1v2
MappedAppdata.saveAsyncAppData.save
MappedAppdata.loadAsyncAppData.getById
MappedAppdata.deleteAsyncAppData.delete
MappedAppdata.allAsyncAppData.get
SimpleQueryQuery
SimpleQuery q = new SimpleQuery(); q.addCriteria("name", "==", storeName);Query q = new Query(); q.equals("name", storeName);

Files

v1v2
com.kinvey.KinveyResourcecom.kinvey.android.File
KinveyResource.uploadFile.upload
KinveyResource.getUriForResourceFile.getDownloadUrl
KinveyResource.openRawResourceFile.download
Got a question?