JSON/XML serialization in Monkey C

Former Member
Former Member
How to parse String with XML or JSON inside?

And how to create XML/JSON string?

Any ideas...
  • If you are trying to send JSON data to a web service, or read JSON data from a web service, this is handled by the Communications module functions already (provided you want to send a full JSON object). For example...

    //var headers = {
    // "Content-Type" => Comm.REQUEST_CONTENT_TYPE_JSON
    //};

    var options = {
    //:method => Comm.HTTP_REQUEST_METHOD_GET,
    //:headers => headers,
    :responseType => Comm.HTTP_RESPONSE_CONTENT_TYPE_JSON
    };

    var params = {
    };

    var url = "jsonplaceholder.typicode.com/.../1";

    Comm.makeWebRequest(url, params, options, method(:onWebResponse));


    If successful, this request will result in the method onWebResponse() being called...

    function onWebResponse(code, data) {
    Sys.println(code);
    Sys.println(data); // this is the JSON data as a Lang.Dictionary
    }


    If you want to send JSON data, you just need to add that data to params and update the request method as is necessary.
  • It is pretty easy to generate a JSON string for the MonkeyC object types, but it is much more difficult to go the other way.. Mostly because the string processing functions are not very powerful. You could probably write code to do it, but it doesn't make any sense.

    The only time you should be reading or writing data would be to save/restore settings or to send/receive data from a web service. The Application.getProperty() and setProperty() APIs and the Communications module functions already take care of these details, eliminating the need for explicit JSON formatting/parsing code.

    Travis
  • Former Member
    Former Member over 8 years ago
    We do not use any web services. We use direct messaging.
    We have XML/JSON string as input (which should be parsed with Monkey C code and used on device).
    And we need to write watch data as XML/JSON string (which will be send to mobile app).

    It is not related to any HTTP web requests. And question is exactly about string manipulation.
    Something like JsonBuilder... XmlBuilder... or at least simple StringBuilder (but of course JsonBuilder / XmlBuilder are much more preferable).
    I think it should be there because SDK works in some way with JSON content of HTTP requests.
    But I cannot find any appropriate API...
  • The functionality you seek is not there.

    I'm still not sure I understand the need to format your message data as XML/JSON. When communicating between a mobile app and a MonkeyC app on the device, you use Communications.transmit() to send an object to the mobile device.. it doesn't need to be a String. You just send an object, which I believe could be a String, Array, Dictionary, Number, Float...

    var object = {
    "1" => [ 1, 2, 3 ],
    2 => "Hello World!"
    };

    Communications.transmit(object, params, new ConnectionListener());


    When you receive data from the mobile device, you use the MailboxIterator, and I believe it will decode the object for you.

    function onMail(mailIterator) {

    var mail = mailIterator.next();
    while (mail != null) {

    // if you need to know what the type of the object was, you can use
    // instanceof to tell. personally, i think it is better to always send a
    // dictionary.

    // assume the mobile app is echoing the message we sent above
    Sys.println(mail)
    Sys.println(mail["1"][0]); // should print 1
    Sys.println(object[2]); // should print "Hello World!"

    mail = mailIterator.next();
    }
    }


    I'm not exactly sure how the code on the mobile device will look, but it should not be difficult; there should be a sample app that is included with the SDK that demonstrates how to send data to a Garmin device from an app running on an iOS/Android mobile device.

    If you have a JSON/XML string on the mobile and want to send it to the device, you can do that, but you'll have to write a bunch of code to parse it on the device. It seems to me that the better solution would be to convert that string into an object representation, and then send that.

    Travis
  • Former Member
    Former Member over 8 years ago
    I'm still not sure I understand the need to format your message data as XML/JSON. When communicating between a mobile app and a MonkeyC app on the device, you use Communications.transmit() to send an object to the mobile device.. it doesn't need to be a String. You just send an object, which I believe could be a String, Array, Dictionary, Number, Float...


    I need to send complex object similar to this one:

    <message>
    <ref>5431<ref>
    <run>1<run>
    <type>Apply<type>
    <results>
    <targets>
    <target>1<target>
    <target>2<target>
    </targets>
    <values>
    <value>0<value>
    <value>15<value>
    </targets>
    </results>
    </message>


    This data cannot be easy represented as Monkey C object.
    Maybe it can be some combination of Dictionary, Arrays and primitives.
    But it is not clear what will be received inside mobile application (from Garmin Android BLE SDK).
    Is it JSONObject? Because if we had to create Java class for each such message then it is a pain in our case I believe.


    If you have a JSON/XML string on the mobile

    Yes

    It seems to me that the better solution would be to convert that string into an object representation, and then send that.

    So it will be significant bunch of classes (for each possible JSON string)...

    // if you need to know what the type of the object was, you can use
    // instanceof to tell. personally, i think it is better to always send a
    // dictionary.


    OK, but what should be send from mobile to get dictionary in watch app?
    If we can prepare such dictionary in some way from JSON string inside mobile app then it can be appropriate.
    But what is the dictionary in mobile? In your words... what should be that "object representation" to get dictionary in Monkey C?


    P.S. Mobile app will support Android platform only.
  • This data cannot be easy represented as Monkey C object.

    Actually, it can quite easily be represented as a MonkeyC object...

    var object = {
    "message" => {
    "ref" => 5431,
    "run" => 1,
    "results" => {
    "targets" => [
    1,
    2
    ],
    "values" => [
    0,
    15
    ]
    }
    }
    };


    Maybe it can be some combination of Dictionary, Arrays and primitives.

    Exactly. That is an object representation.

    But it is not clear what will be received inside mobile application. Is it JSONObject?

    I downloaded the Android SDK and opened the documentation (MobileSDK.html) and found the following...

    You can send messages to your Connect IQ application on a connected device using any of the Java equivalent Monkey C data types (see Supported Data Types table below). Calling sendMessage() will deliver the message to your applications mailbox.


    Scanning down from there, you can see the object mapping from Java to MonkeyC...

    Supported Data Types
    Java Data Type — Monkey C Type
    int, Integer — Integer
    float, Float — Float
    boolean, Boolean — Boolean
    String — String
    List<?> — Array[] — Note: List must contain only supported data types. If the list contains unsupported data types, an exception will be thrown.
    Map<?,?> — Dictionary — Note: Map keys and values must be supported data types. If the map contains unsupported data types, an exception will be thrown.


    So when sending data to the ConnectIQ application from Android you send an aggregate of Map, List, String, boolean, float, or int. When the data is received on the Garmin, you'll get an equivalent aggregate of Dictionary, Array, String, Boolean, Float or Number.

    The documentation doesn't come right out and say that this behavior is symmetrical, but I'm fairly certain that you can assume that it is. The message data that is received on the Android side is a List<Object>. I'm sure a few minutes of testing will verify that the first element of that list would be the object that is sent.

    So, if the data you get is already in the necessary object representation (aggregate of Maps, Lists, ...), then you're done. You just need to send that data along to the mobile application directly. If the data comes to your Java application as an XML String representation, you need to convert it to this object representation and send it. I did some searching on google and it looks like there are plenty of ways to do this.

    Travis