About Communications return data exception issue

I want to create an app that displays stock prices and plan to use Tencent's free stock interface. However, the data returned in the code is different from the data returned in Postman. I want to get the correct data returned, how should I handle it? Below is my example code and screenshot.

class JsonTransaction extends Toybox.System.ServiceDelegate {

function initialize() {
Sys.ServiceDelegate.initialize();
}
function onTemporalEvent() {
}


function onReceive(responseCode as Number, data as Null or Dictionary or String or PersistedContent.Iterator) as Void {
if (responseCode == 200) {
Sys.println("Response: " + data);
Background.exit(data);
} else {
System.println("Response: " + responseCode);
Background.exit("");
}
}

function makeRequest(url) as Void {

var params = {};

var options = { // set the options
:method => Communications.HTTP_REQUEST_METHOD_GET, // set HTTP method
// :headers => { // set headers
// "Content-Type" => Communications.HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN},
// set response type
:responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_TEXT_PLAIN
};

var responseCallback = method(:onReceive);
Communications.makeWebRequest(url, params, options, responseCallback);
}

}
  • Strange. Some of it might be known bugs of the console, that displays different things depending on characters. But these look much more different.

    Maybe the backend detects the user agent and returns different response.

    Try to set up a web server, send the same request to it, and log what exactly was received by your web server, then create a postman or curl query and send it (exactly as your webserver received it) to the real API. Maybe then you'll also get the same result that you get in the simulator 

  • Looks to me you are including a parameter as part of the url (=s_sh600519) where you need to specify it as a param (which you have as {})

  • It's not a url parameter, it just looks like one because of the "=" character. Note that:

    - there's no "?" in the url. url params are key/value pairs following the first "?" in a url

    - if you open the url as written, it returns the data in the screenshot:

    https://qt.gtimg.cn/q=s_sh600519 

  • TL;DR I think it's a problem with the sim.

    - System.println() (to the dev console) seems to start printing nonsense at the first East Asian char in the response and never recovers

    - In the sim, if you display the response on a device screen (e.g. fr955), the East Asian characters are replaced by garbage, but the non-East Asian characters are displayed properly (even characters which come after East Asian characters)

    - on a real device (e.g. fr955), the response seems to be printed properly (at least the part of it that will fit on the screen). I am able to see this much on a real device by simply creating a simple data field, making the webrequest and return the response in compute():

    _s_sh600519="1~贵州茅台~600519~15

    Some of it might be known bugs of the console, that displays different things depending on characters. But these look much more different.

    I don't think it's a coincidence that the string starts to be rendered incorrectly precisely at the first East Asian character.

    This is the output from the API (when I call the API myself using the given url):

    v_s_sh600519="1~贵州茅台~600519~1580.00~-0.97~-0.06~15090~238124~~19847.93~GP-A";

    And this is the output in the console (from the screenshot)

    v_s_sh600519=\"1~[3]...

    Ofc the \ character before the double quote is a known bug / quirk when printing strings the console using System.println (in general, escape characters are for string literals in source code, not output, and System.println doesn't even escape other characters which would be escaped in string literals, only double quotes.)

    Other than that, both strings are the same right up until "贵" - the first East Asian character in the string.

    My guess would be that System.println doesn't handle East Asian characters properly, at least when it prints to the console on a dev machine. I would try printing the string (or at least part of it) to the device display itself (either sim or real device).

    I would also try assigning the string to a global or class variable, and viewing the contents in the sim's memory viewer.

    EDIT: I tried this test in the sim and:

    - the memory viewer just shows nothing for the value of the returned data (I guess it doesn't like the East Asian characters), although it does say the size of the string is 92 bytes

    - if I try to display the string on the simulated device screen, the non-East Asian characters display properly, but the East Asian characters are replaced with garbage. (At least for the first part of the string up to "~6", since the string is too long to fit on the width of the device). Changing the language in the simulator to Chinese (Standard) or Chinese (Traditional) did not seem to help.

    Basically, I created a simple data field which makes the web request and returns the response data in compute().

    On a real watch (fr955 which only has a single part number for both WW and APAC), the string seems to be displayed properly. (At least the part that will fit on the screen). I see roughly this:

    _s_sh600519="1~贵州茅台~600519~15

    So it could be that the problem is only in the simulator, and that at least displaying the string would work properly on a real device with support for East Asian characters. Idk if functions like String.substring will work properly tho

  • Thank you for your help, it is indeed that System.println() did not print out Chinese characters.