Juxture Juxture - 25 days ago 6
Android Question

Custom deserializer for RealmObject

For learning purposes i'm creating an android app by using Realm and the Edinburg Festival Api. It's going pretty well except for one problem.

I'm using the following to convert the retrieved JSON to RealmObjects:

public void onResponse(final String response) {
realm.executeTransactionAsync(new Realm.Transaction(){
@Override
public void execute(Realm realm) {
// Update our realm with the results
parseImages();
realm.createOrUpdateAllFromJson(Festival.class, response);
}
}
}


This works fine except for one field, the images. The image part of the JSON:

"images": {
"031da8b4bad1360eddea87e8820615016878b183": {
"hash": "031da8b4bad1360eddea87e8820615016878b183",
"orientation": "landscape",
"type": "hero",
"versions": {
"large-1024": {
"height": 213,
"mime": "image/png",
"type": "large-1024",
}
"width": 1024
}
}


The problem here is the hash inside the image object. I have no clue how to handle this. The hash is different for every festival. Would it be possible to to make a custom JSON deserializer in my RealmObject?

Last code sample is my current model:

public class Festival extends RealmObject {
@PrimaryKey
public String title;
RealmList<Image> images;
public String description_teaser;
public String description;
public String genre;
public String age_category;
public String website;
public RealmList<Performance> performances;
public int votes;
}


I'm aware my PK is not optimal but this is still just testing to get the images working and i needed to set a PK for migrating.

Any tips are welcome, cheers :)

Update



Added the image model:

public class Image extends RealmObject {
public String hash;
public String orientation;
public String type;
RealmList<Version> versions;
}


Update 2



My attempt to parse the images before calling realm.createOrUpdateAllFromJson(Festival.class, response);

private void parseImages(String jsonString) throws JSONException {
JSONArray jsonArr = new JSONArray(jsonString);
for(int i = 0; i < jsonArr.length(); i++){
JSONObject jsonObj = jsonArr.getJSONObject(i);
JSONObject images = (JSONObject)jsonObj.get("images");
Iterator<String> iter = images.keys();
while (iter.hasNext()) {
String key = iter.next();
try {
JSONObject value = json.get(key);
realm.createOrUpdateObjectFromJson(Image.class,value);
} catch (JSONException e) {
// Something went wrong!
}
}
}
}

Answer

Due to how the keys are dynamic in this JSON (why isn't this an array? Whoever designed this API had no idea what they were doing), you'll have to manually parse the object up to the point of the hash key:

JSONObject jsonObj = new JSONObject(jsonString);
JSONObject images = (JSONObject)jsonObj.get("images");
Iterator<String> iter = images.keys();
while (iter.hasNext()) {
    String key = iter.next();
    try {
        JSONObject value = json.get(key);
        realm.createOrUpdateObjectFromJson(Image.class, value.toString());
    } catch (JSONException e) {
        // Something went wrong!
    }
}
Comments