FatFractal customer forums

NoServer => NoServer Questions and Answers => Topic started by: erka on March 07, 2014, 05:26:32 AM

Title: NSDictionary equivalent in Android
Post by: erka on March 07, 2014, 05:26:32 AM
In iOS we can store NSDictionary in a datatype of UNVALIDATED. What is the equivalent in Java/Android?

We tried using JSONObject which didn't give any errors but the result was a empty object.


Example data:
Code: [Select]
{
    "circleViewFrames": [
        {
            "circleView1": {
                "Height": 70,
                "Width": 70,
                "Y": 150,
                "X": 140
            }
        },
        {
            "circleView2": {
                "Height": 70,
                "Width": 70,
                "Y": 100,
                "X": 200
            }
        },
        {
            "circleView3": {
                "Height": 70,
                "Width": 70,
                "Y": 60,
                "X": 40
            }
        },
        {
            "circleView4": {
                "Height": 70,
                "Width": 70,
                "Y": 150,
                "X": 50
            }
        },
        {
            "circleView5": {
                "Height": 70,
                "Width": 70,
                "Y": 50,
                "X": 180
            }
        }
    ]
}
Title: Re: NSDictionary equivalent in Android
Post by: kevin@fatfractal.com on March 07, 2014, 10:55:44 AM
You can use java.util.HashMap/ java.util.Map

Kevin
Title: Re: NSDictionary equivalent in Android
Post by: erka on March 07, 2014, 11:43:54 AM
I tried using HashMap<Object, Object> but it gave me errors:

"03-07 17:13:22.215: W/System.err(11027): FFException{httpStatusCode=-1, message=IOException [Unexpected token (START_OBJECT), expected VALUE_STRING: need JSON String that contains type id (for subtype of java.lang.Object)"

How would I go about getting the example data into a HashMap?
Title: Re: NSDictionary equivalent in Android
Post by: gkc on March 07, 2014, 12:20:09 PM
If you can wait until tomorrow, I am releasing next version of Android SDK which will default to I marshalling to HashMap if no explicit mapping supplied
Title: Re: NSDictionary equivalent in Android
Post by: kevin@fatfractal.com on March 07, 2014, 12:24:24 PM
Thanks, Gary!

My apologies erka - I thought that would work for you, but I was wrong.

Kevin
Title: Re: NSDictionary equivalent in Android
Post by: gkc on March 09, 2014, 01:34:05 PM
FYI: Latest version of Android SDK released which will deserialize to HashMap if no explicit mapping supplied. See http://fatfractal.com/docs/getting-started/#release-notes and http://fatfractal.com/support/downloads/
Title: Re: NSDictionary equivalent in Android
Post by: kevin@fatfractal.com on March 09, 2014, 06:19:22 PM
Well, I guess I can say that now I am right  ;D
Title: Re: NSDictionary equivalent in Android
Post by: erka on March 10, 2014, 06:28:07 AM
I downloaded the latest Android SDK R1.2.2.2 (though the jar is still named FF-Android-SDK-R1.2.0.jar) and I'm getting the same error.
Could you provide me with an example how I should declare the HashMap to get the example data working?

Title: Re: NSDictionary equivalent in Android
Post by: gkc on March 10, 2014, 09:37:59 AM
Just don't declare any mapping, and you will get a HashMap
Title: Re: NSDictionary equivalent in Android
Post by: erka on March 10, 2014, 10:30:05 AM
I only want to map some specific properties to HashMaps. I tried removing the mapping as you said (//FFObjectMapper.registerClassNameForClazz(MinigameData.class.getName(), "MinigameData")) which still gave me errors:

"03-10 15:08:14.699: W/System.err(27785): FFException{httpStatusCode=-1, message=IOException [Unexpected token (END_OBJECT), expected FIELD_NAME: missing property 'clazz' that is to contain type id  (for class java.lang.Object)"

This is my model:
Code: [Select]
public class MinigameData {
private Minigame minigame;
private Match match;
private HashMap<Object, Object> data;
private HashMap<Object, Object> owner;
private HashMap<Object, Object> opponent;
private int index;

public MinigameData() {}

public Minigame getMinigame() {
return minigame;
}
public void setMinigame(Minigame minigame) {
this.minigame = minigame;
}
public Match getMatch() {
return match;
}
public void setMatch(Match match) {
this.match = match;
}
public HashMap<Object, Object> getData() {
return data;
}
public void setData(HashMap<Object, Object> data) {
this.data = data;
}
public HashMap<Object, Object> getOwner() {
return owner;
}
public void setOwner(HashMap<Object, Object> owner) {
this.owner = owner;
}
public HashMap<Object, Object> getOpponent() {
return opponent;
}
public void setOpponent(HashMap<Object, Object> opponent) {
this.opponent = opponent;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
Title: Re: NSDictionary equivalent in Android
Post by: gkc on March 10, 2014, 04:02:35 PM
Oh I see. Ok I will look into this particular use case
Title: Re: NSDictionary equivalent in Android
Post by: gkc on March 10, 2014, 04:10:08 PM
This code works for me. I am mapping the 'containing' class only ...

Code: [Select]
    public static class TestContainedHashMap {
        private String title;
        private Map<String, Object> data;
        public String getTitle() { return title; }
        public void setTitle(String title) { this.title = title; }
        public Map<String, Object> getData() { return data; }
        public void setData(Map<String, Object> data) { this.data = data; }
    }
    @Test
    public void testContainedHashMapCreateAndRetrieve() throws FFException, URISyntaxException {
        FatFractal ff = TestUtils.getFF();
        if (ff == null) return;

        final String clazz = "TestContainedHashMap";
        final String collectionName = "/" + clazz;

        FFObjectMapper.registerClassNameForClazz(TestContainedHashMap.class.getName(), clazz);
        TestUtils.deleteIfExists(ff, collectionName);

        ff.login("gary", "gary");

        TestContainedHashMap obj = new TestContainedHashMap();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("aString", "abcde");
        map.put("aBoolean", false);
        obj.setTitle("Hello, world");
        obj.setData(map);

        ff.createObjAtUri(obj, collectionName);

        ff.forgetObj(obj);

        final List<Object> arrayFromUri = ff.getArrayFromUri(collectionName);
        assertEquals(1, arrayFromUri.size());
        final Object retrievedObj = arrayFromUri.get(0);
        assertTrue(retrievedObj instanceof TestContainedHashMap);
        assertEquals(map, ((TestContainedHashMap) retrievedObj).getData());
    }


PS Thanks for pointing out the inconsistency in the jar file name. Have corrected and re-released.
Title: Re: NSDictionary equivalent in Android
Post by: erka on March 11, 2014, 06:06:46 AM
It works with simple string/object pairs like your example. The problem is with more complex nesting like in the example data I provided that was originally originated from a NSDictionary. Maybe this kind of parsing is not possible in Android and we'll have to simplify the data?
Title: Re: NSDictionary equivalent in Android
Post by: gkc on March 11, 2014, 06:56:44 AM
OK have reproduced - will fix
Title: Re: NSDictionary equivalent in Android
Post by: gkc on March 11, 2014, 02:16:46 PM
Fixed, I believe. Available as "pre-release" from https://system.fatfractal.com/repo/artifact/Releases/R1.2.2.3/FF_ANDROID_SDK_R1.2.2.3_R2689.zip


NOTE: Please always check here for latest releases : http://fatfractal.com/downloads
Title: Re: NSDictionary equivalent in Android
Post by: erka on March 12, 2014, 07:17:42 AM
It works. Thank you kevin and gkc for your swift response and fix!

This is the code I use for getting the values out of the Map incase anyone needs it or have suggestions for improvements:
Code: [Select]
try {
List<MinigameData> minigameData = ff.getArrayFromUri("/MinigameData");

for(int i = 0; i < minigameData.size(); i++) {

Map<String, Object> data = minigameData.get(i).getData();

if(data != null && data.containsKey("circleViewFrames")) {

ArrayList<Map> circleViewFrames = (ArrayList) data.get("circleViewFrames");

for(int c = 0; c < circleViewFrames.size(); c++) {
String circleId = String.valueOf(c+1);
Map<String, Object> circleView = circleViewFrames.get(c);
Map<String, Object> circleViewProperties = (Map) circleView.get("circleView" + circleId);
Integer height = (Integer) circleViewProperties.get("Height");
Integer width = (Integer) circleViewProperties.get("Width");
Integer x = (Integer) circleViewProperties.get("X");
Integer y = (Integer) circleViewProperties.get("Y");
}
}
}

} catch (FFException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Title: Re: NSDictionary equivalent in Android
Post by: kevin@fatfractal.com on March 12, 2014, 11:59:47 AM
Yay!!

All thanks to Gary (gkc) - he did all the real work.

Appreciate your patience.

Kevin