出于学习目的,我正在使用Realm和Edinburg Festival Api创建一个Android应用程序。除了一个问题外,它还是很顺利的。
我正在使用以下内容将检索到的JSON转换为RealmObjects:
Option Explicit
Function IsName(NameOfName) As Boolean
Dim check As Name
On Error Resume Next
Set check = ActiveWorkbook.Names(NameOfName)
On Error GoTo 0
If check Is Nothing Then
IsName = False
Else
IsName = True
End If
End Function
Sub TestIsName()
Dim test As Boolean
test = IsName("name1")
Debug.Print (test)
End Sub
除了一个字段,图像外,这个工作正常。 JSON的图像部分:
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);
}
}
}
这里的问题是图像对象内的哈希。我不知道如何处理这个问题。每个节日的哈希都不同。是否可以在我的RealmObject中创建自定义JSON反序列化器?
最后一个代码示例是我当前的模型:
"images": {
"031da8b4bad1360eddea87e8820615016878b183": {
"hash": "031da8b4bad1360eddea87e8820615016878b183",
"orientation": "landscape",
"type": "hero",
"versions": {
"large-1024": {
"height": 213,
"mime": "image/png",
"type": "large-1024",
}
"width": 1024
}
}
我知道我的PK不是最佳的,但这仍然只是测试以使图像正常工作,我需要设置PK以进行迁移。
欢迎任何提示,欢呼:)
添加了图像模型:
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;
}
我尝试在调用realm.createOrUpdateAllFromJson(Festival.class,response)之前解析图像;
public class Image extends RealmObject {
public String hash;
public String orientation;
public String type;
RealmList<Version> versions;
}
我创建了一个函数来清理我从API获得的破坏的JSON。这不是很好,但它现在有效。它删除了哈希和奇怪的版本,只是将它们放在一个数组中。我确信它可以更有效地编写,但我会继续使用这个,所以我现在可以继续我的应用程序的其余部分。看看我自己的答案。
答案 0 :(得分: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;
}
希望它可以帮助某人:)但是确定无所事事。
答案 1 :(得分: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!
}
}