[TIMOB-26118] iOS: Add new ES6 "String" methods to iOS 8
GitHub Issue | n/a |
---|---|
Type | Improvement |
Priority | Medium |
Status | Closed |
Resolution | Won't Do |
Resolution Date | 2018-09-18T19:56:22.000+0000 |
Affected Version/s | Release 7.1.0 |
Fix Version/s | n/a |
Components | iOS |
Labels | es6, ios |
Reporter | Joshua Quick |
Assignee | Joshua Quick |
Created | 2018-06-08T23:20:28.000+0000 |
Updated | 2018-09-18T21:47:28.000+0000 |
Description
*Summary:*
iOS 8 does not support the following new ES6 "String" methods when "tiapp.xml" setting
<transpile>
is set to true
. We should add them so that ES6 support is consistent between iOS versions.
* String.prototype.startsWith()
* String.prototype.endsWith()
* String.prototype.includes()
* String.prototype.repeat()
*Steps to reproduce:*
Set up a project's "tiapp.xml" with the below "transpile" setting.
Build and run the below code on iOS 8.
<?xml version="1.0" encoding="UTF-8"?>
<ti:app xmlns:ti="http://ti.appcelerator.org">
<transpile>true</transpile>
</ti:app>
Ti.API.info("@@@ String.startsWith: " + (typeof String.prototype.startsWith));
Ti.API.info("@@@ String.endsWith: " + (typeof String.prototype.endsWith));
Ti.API.info("@@@ String.includes: " + (typeof String.prototype.includes));
Ti.API.info("@@@ String.repeat: " + (typeof String.prototype.repeat));
var message = "Hello World";
Ti.API.info("@@@ String.startsWith() works? " + message.startsWith("Hello"));
Ti.API.info("@@@ String.endsWith() works? " + message.endsWith("World"));
Ti.API.info("@@@ String.includes() works? " + message.includes("ello"));
Ti.API.info("@@@ String.repeat() works? " + ("a".repeat(3) === "aaa"));
*Result:*
The above throws an exception on iOS 8 because the new ES6 String methods are undefined.
The above works fine on iOS 9 and newer iOS versions.
The above works fine on Android as well.
Attachments
File | Date | Size |
---|---|---|
String.js | 2018-06-11T18:54:53.000+0000 | 2236 |
We could use "polyfill" as mentioned here: [TIMOB-25816] Alternatively, we can add these methods to the
String.prototype
ourselves if we bootstrap the "app.js" loading on all platforms as proposed here: [TIMOB-26015] _(This is the faster/simpler approach.)_I'd vote either for the polyfill or adding it on a native level. Using the shell-file for that feels wrong to me.
Implementing the missing functions via a JS file is exactly how it would work via polyfill and a webpage's JS. A polyfill is just an ES5 implementation of ES6 functions. Case-in-point, Mozilla shows devs how to implement their own polyfill of the
startsWith()
function below. Although their implementation can be optimized to use anindexOf()
instead, but the point is that you can just implement your own JavaScript function if it's missing. Pretty easy. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith Also, I've already done it now. :) See attached [^String.js] _(I'll see about optimizing myendsWith()
function further to remove thesubstr()
call.)_ I'm not saying we should implement all of the ES6 functions ourselves. But we can implement the popular ones. Especially since Titanium supports disabling trasncoding.[~jquick] The main reason for the babel-polyfill is that it would only be applied to targets that do not support it already, so it reduces the overhead of the built-in scripts. Also, see TIMOB-26123 for the general iOS 8 removal.
I do agree that a native implementation would be superior to a polyfill via JavaScript. Especially for the
String.prototype.repeat()
method. For now, I need a solution since the core JS scripts I'm introducing to all platforms needs a couple of these functions and it's convenient to have them via our own polyfill. Only Android and Windows would be punished by this overhead (which I think is negligible) since they already have these ES6 functions. But an iOS app would always have these polyfills while the min iOS version supported is iOS 8. So, iOS requires the polyfill overhead unless we add these functions natively. If you can offer me an alternative then I would love to hear it.PR (master): https://github.com/appcelerator/titanium_mobile/pull/10112
Titanium now supports ES6 polyfill when "tiapp.xml" transpile setting is set
true
. That is expected to be used instead. Closing.FR Passed.
ES6 "String"
methods works with IOS 8 when<transpile>true</transpile>
Studio Ver: 5.1.1.201809051655 SDK Ver: 7.5.0.v20180913121236 OS Ver: 10.13.5 Xcode Ver: Xcode 9.4.1 Appc NPM: 4.2.13 Appc CLI: 7.0.6 Daemon Ver: 1.1.3 Ti CLI Ver: 5.1.1 Alloy Ver: 1.13.2 Node Ver: 8.9.1 NPM Ver: 5.5.1 Java Ver: 10.0.2 IOS Simulator: 8.4Please ignore above FR comment. The ticket was closed & I had not refreshed my webpage,