2016-11-10 43 views
0

为了学习的目的,我使用Realm和Edinburg Festival Api创建了一个Android应用程序。除了一个问题之外,它会很好。RealmObject的自定义解串器

我使用以下检索到的JSON转换为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); 
     } 
    } 
} 

这工作只有一个行业例外,图像精细。 JSON的图像部分:

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

这里的问题是图像对象中的散列。我不知道如何处理这个问题。哈希每个节日都有所不同。是否有可能在我的RealmObject中创建一个自定义的JSON解串器?

最后的代码示例是我目前的模型:

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; 
} 

我知道我的PK是不是最优的,但是这还只是测试,以获得工作的图片,我需要设置PK迁移。

任何提示,欢迎,欢呼:)

更新

添加了图像模型:

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

更新2

我尝试打电话realm.createOrUpdateAllFromJson前解析图像(Festival.class,回应);

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! 
      } 
     } 
    } 
} 

更新3

我创建了清理破碎的JSON我从API获得的功能。这不是很好,但它现在工作。它删除了哈希和奇怪的版本,并将它们放在一个数组中。我确信它可以更有效地写入,但我只是去这个,所以我现在可以继续我的应用程序的其余部分。看到我自己的答案。

回答

1

我自己的临时解决方案:

/** 
    * Function to fix the json coming from the Festival API 
    * This is a bit more complicated then it needs to be but realm does not yet support @Serializedname 
    * It removes the "large-1024" (and simllar) object and places the versions in a JSON version array 
    * Then it removes the hashes and creates and images array. The JsonArray can now be parsed normally :) 
    * 
    * @param jsonString Result string from the festival api 
    * @return JSONArray The fixed JSON in the form of a JSONArray 
    * @throws JSONException 
    */ 
    private JSONArray cleanUpJson(String jsonString) throws JSONException { 
     JSONArray json = new JSONArray(jsonString); 
     for(int i = 0; i < json.length(); i++){ 
      // We store the json Image Objects in here so we can remove the hashes 
      Map<String,JSONObject> images = new HashMap<>(); 
      JSONObject festivalJson = json.getJSONObject(i); 
      JSONObject imagesJson = (JSONObject)festivalJson.get("images"); 
      // Iterate each hash inside the images 
      Iterator<String> hashIter = imagesJson.keys(); 
      while (hashIter.hasNext()) { 
       String key = hashIter.next(); 
       try { 
        final JSONObject image = imagesJson.getJSONObject(key); 

        // Remove the version parents and map them to version 
        Map<String, JSONObject> versions = new HashMap<>(); 
        JSONObject versionsJsonObject = image.getJSONObject("versions"); 

        // Now iterate all the possible version and map add to the hashmap 
        Iterator<String> versionIter = versionsJsonObject.keys(); 
        while(versionIter.hasNext()){ 
         String currentVersion = versionIter.next(); 
         versions.put(currentVersion,versionsJsonObject.getJSONObject(currentVersion)); 
        } 

        // Use the hashmap to modify the json so we get an array of version 
        // This can't be done in the iterator because you will get concurrent error 
        image.remove("versions"); 
        Iterator hashMapIter = versions.entrySet().iterator(); 
        JSONArray versionJsonArray = new JSONArray(); 
        while(hashMapIter.hasNext()){ 
         Map.Entry pair = (Map.Entry)hashMapIter.next(); 
         versionJsonArray.put(pair.getValue()); 
        } 
        image.put("versions",versionJsonArray); 
        Log.d(LOG_TAG,image.toString()); 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
       images.put(key,imagesJson.getJSONObject(key)); 
      } 
      // Now let's get rid of the hashes 
      Iterator hashMapIter = images.entrySet().iterator(); 
      JSONArray imagesJsonArray = new JSONArray(); 
      while(hashMapIter.hasNext()){ 
       Map.Entry pair = (Map.Entry)hashMapIter.next(); 
       imagesJsonArray.put(pair.getValue()); 
      } 
      festivalJson.put("images", imagesJsonArray); 
     } 
     return json; 
    } 

希望它可以帮助别人:)但肯定是不整齐。

+0

好的 - ------ – EpicPandaForce

0

由于关键是如何动态的,这JSON(为什么不是这样的数组谁设计了这个API根本不知道他们在做什么?),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! 
    } 
} 
+0

感谢您的回答。我如何将这与目前我解析json的方式结合起来?我应该@ignore图像,然后运行此代码添加图像后?或者我可以以某种方式实现这realm.createOrUpdateAllFromJson内? – Juxture

+0

您需要其送入之前运行该代码'createOrUpdateAllFromJson' –

+0

每个图像对象应分别作为对象被存储,同时通过键解析图像一个接一个。哈希本身也可以在对象中找到,毕竟,所以你不会丢失任何信息。 'createOrUpdateAll'需要一个数组,但这不是一个数组。 – EpicPandaForce