{ "id": "62351", "key": "TIMOB-1719", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": { "id": "2", "description": "The problem described is an issue which will never be fixed.", "name": "Won't Fix" }, "resolutiondate": "2017-07-26T03:23:04.000+0000", "created": "2011-04-15T03:00:26.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "core" ], "versions": [ { "id": "13505", "description": "Release 3.0.0", "name": "Release 3.0.0", "archived": true, "released": true, "releaseDate": "2012-12-14" } ], "issuelinks": [], "assignee": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2017-07-26T03:23:04.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "{html}
This was addressed on Android, over to iOS for parity. Below are\r\nthe notes Bill wrote in the original bug. From #1690
\r\nUse case (helpdesk 38891): app fetches data via XHR. Data is XML\r\nencoded in ISO-8859-1. Data is saved to file, to be opened later.\r\nWhen re-opened, Titanium forces it to UTF-8, which screws up the\r\nencoding of some of the special characters such as those with\r\numlaute (ö, ä etc) or accents (é etc).
\r\nFail case:
\r\nscript to repro:
\r\nTitanium.UI.setBackgroundColor('#000');
\r\nvar win = Titanium.UI.createWindow({
\r\ntitle:'Feed encoding test',\r\nbackgroundColor:'#fff',\r\nfullscreen: true,\r\nexitOnClose: true,\r\nurl: 'main.js'
\r\n
\r\n}); win.open();
\r\nmain.js:
var win = Ti.UI.currentWindow;
\r\nwin.title = \"Feed encoding via file\"
\r\nvar url = [SEE HELPDESK 38891]
var dir = Titanium.Filesystem.applicationDataDirectory;
\r\nvar filename = 'feed.xml';
\r\nvar file = Ti.Filesystem.getFile(dir, filename);
function saveFeed(data) {
\r\nif (file.exists()){\r\n file.deleteFile();\r\n}\r\nfile.write(data);
\r\n
\r\n}
\r\nfunction buildTable() {
\r\nvar blob = file.read();\r\nvar string = blob.text;\r\nvar xml = Ti.XML.parseString(string);\r\nvar rows = [];\r\ntry {\r\n if (xml) {\r\n var session = xml.getElementsByTagName('session');\r\n if (session) {\r\n session = session.item(0);\r\n } else { \r\n alert('session list not fetched');\r\n return;\r\n }\r\n if (session) {\r\n if (!session.hasChildNodes()) {\r\n alert('No child nodes');\r\n return;\r\n }\r\n var length = session.childNodes.length;\r\n for (var i = 0; i < length; i++) {\r\n var child = session.childNodes.item(i);\r\n if (child.nodeType == child.ELEMENT_NODE) {\r\n rows.push(Ti.UI.createTableViewRow({color: 'black', title: child.getAttribute(\"driver\")}));\r\n }\r\n }\r\n win.add(Ti.UI.createTableView({data: rows}));\r\n } else {\r\n alert('\"session\" not found');\r\n }\r\n } else {\r\n alert('XML did not load');\r\n }\r\n} catch(ex) {\r\n alert(ex);\r\n}
\r\n
\r\n}
\r\nvar xhr = Ti.Network.createHTTPClient();
\r\nxhr.onload = function(e) {
\r\ntry {\r\n var data = xhr.responseData;\r\n saveFeed(data);\r\n buildTable();\r\n\r\n} catch(ex) {\r\n alert(ex);\r\n}
\r\n
\r\n}; xhr.open('GET', url);
\r\nxhr.send();
more of Bills notes:
\nWe want to keep things internally in UTF-8, so instead of trying to\ntrack the other encoding throughout its lifetime in Titanium code\n(i.e., in TiBlob, TiFile, etc), we now give the developer a way to\ntranscode the text to utf-8 and then save that:
\nvar utf8Text = Ti.Utils.transcodeString(origText, 'ISO-8859-1',\n'UTF-8');
\nSo Ti.Utils.transcodeString(origText, origEncoding,\ndesiredEncoding) is new.
\nTo fix the fail case from the description of this item, in the\nfunction saveFeed change file.write(data) to\nfile.write(Ti.Utils.transcodeString(data, 'ISO-8859-1',\n'UTF-8')).
\nThen, because the feed contains <?xml version=\"1.0\"\nencoding=\"ISO-8859-1\"?>, you need to change the encoding= to\nread encoding='UTF-8 before giving it to the xml parser. So in\nbuildTable() change ...
\nvar xml = Ti.XML.parseString(string);
\n... to ... var xml =\nTi.XML.parseString(string.replace(/iso-8859-1/i, 'UTF-8'));
\nFinally, when the data comes back from the provider, get it with\nresponseText instead of responseData
\n. So replace this... var data = xhr.responseData;
\nwith this ...
var data = xhr.responseText;
\nalso
\nxhr.responseData with xhr.responseText
the current behavior is the test generates an alert on iOS. I\nposted the working test case (resource files) to\nAppcelerator/Users/Thomas/bugs/1719 if that helpful
We added Ti.Utils.transcodeString
, so Ti iOS should\nget one too for parity. Here's the java, fyi:
\npublic String transcodeString(String orig, String inEncoding, String outEncoding)\n {\n try {\n \n Charset charsetOut = Charset.forName(outEncoding);\n Charset charsetIn = Charset.forName(inEncoding);\n\n ByteBuffer bufferIn = ByteBuffer.wrap(orig.getBytes(charsetIn.name()) );\n CharBuffer dataIn = charsetIn.decode(bufferIn);\n bufferIn.clear();\n bufferIn = null;\n\n ByteBuffer bufferOut = charsetOut.encode(dataIn);\n dataIn.clear();\n dataIn = null;\n byte[] dataOut = bufferOut.array();\n bufferOut.clear();\n bufferOut = null;\n \n return new String(dataOut, charsetOut.name());\n \n } catch (UnsupportedEncodingException e) {\n Log.e(LCAT, \"Unsupported encoding: \" + e.getMessage(), e);\n }\n return null;\n }
\n
We could leave this as an entrance test for new hires. Very\nclean and clearcut function.