Can Swift Scripts Execute in a Swift iOS App? - javascript

We have an iOS app (Obj-C) that grabs a JavaScript file from AWS S3 to run our proprietary algorithm on a bunch of raw image data right on the iPhone (Lambda functions produced some latency I guess). For the sake of security, the JavaScript is obfuscated and entirely unreadable, and even harder to debug.
Well, the JavaScript is spitting out NaN result values back to the iPhone, and I am seriously struggling to even find where this NaN pollution starts. Very frustrating.
Behind the scenes I am working on refactoring this entire project to leverage Swift instead. It's much easier to dev/maintain than Objective-C (IMHO). Also, Swift can be used for scripting, so I'm thinking I can just reduce my tech stack by removing the JavaScript entirely.
Question: Can a Swift script execute in a Swift iPhone app the same way JavaScript can? If yes, how?
The Objective-C code snippet (modified for brevity)
functionCall = [NSString stringWithFormat: #"some JS function call"];
[jsContext evaluateScript: functionCall];
JSValue* jsv = [jsContext objectForKeyedSubscript: #"result"];
NSDictionary* result = [jsv toDictionary];
// result is != nil, but the values are all NaN
// Can't find the error when debugging JavaScript in Chrome
// C# utility app that does the same thing produces good results
I am aware that Apple will reject an app for the App Store if using an obfuscation tool on the source code is detected, or I'd consider purchasing a license for one. Also, we have an identical Android app, so if I can do the same with Kotlin scripts then I'll be a happy camper.
Another concern I have is if the obfuscated JavaScript code is even increasing the security. I understand that a jailbroken device can access device memory and get a hold of code at runtime, which makes me think I'm performing an exercise in futility. Phrased differently, is the obfuscated JavaScript effectively more secure than manually/primitively obfuscated Swift source code?

As user jvnpdx stated, it is not possible to dynamically run a Swift script within the app.

Related

How to debug javascript with Eclipse running local Tomcat server

There are a lot of questions on SO about how to debug a standalone piece of Javascript - that isn't what I want. None of the previous Eclipse/javascript questions seem to be on point, which surprised me.
I am using Eclipse for Java EE (Neon, the latest version) to develop a JSP/servlet website - a full website, not just javascript, and not just java/jsp - everything together. I can compile my Java and "debug as" on an instance of Tomcat spawned by Eclipse, and the web pages show up inside of a window in Eclipse. I can set and hit Java breakpoints all day long while using "debug as" - but setting breakpoints in javascript doesn't do diddly squat. I've been having to run a standalone instance of Tomcat, deploy war files to it, wait for the war files to decompress, then debug my Javascript inside of Firefox. This is particularly annoying because I'm relatively new to javascript and am doing some complex things on the page (and truth be told, making some silly mistakes a compiler in a typed language would catch for me before letting me waste my time trying to run the code) and the "change, watch Eclipse chew deploying war, wait for Tomcat to chew uncompressing the war, test" cycle is just unacceptably long.
Isn't there an easier way to debug BOTH java and javascript from the same IDE without having to export and deploy WAR files? Is there is a setting I can toggle or something I can install in Eclipse to make it an all-in-one IDE? Ideally I would like to be able to step through, for example, an AJAX call into my servlet AND watch what happens in the javascript after it returns - within the same debugging session - so let me preemptively state that copying the changed js file(s) directly to the decompressed folder in tomcat/webapps as a faster way to continue to do split debugging is not the kind of "workaround answer" I'm looking for.
JavaScript debugging is going to be supported in Eclipse Neon 1 release (September 2016). Here is a demo video in which step-by-step process of debugging both front-end and back-end is explained - https://youtu.be/7oQz1Ja1H08 .
Basically, running Chrome / Chromium with extra parameters and tuning source mapping manually is not really user-friendly now, but we are going to improve it for Neon 1 and future releases.
Contributions of any kind are most welcome ;)

Is there any way to simulate command line interaction in browser javascript?

I don't have a lot of hope for this one, but I have to ask. I am hoping, for didactic purposes, to come up with some means by which a student could load a simple javascript program into a browser, and have it interact with them in the old-fashioned command line manner, where it prints a line and then reads a line of input. This works fine if you use prompt(), but the fact that it creates popups is aesthetically annoying, and today's browsers cheerfully volunteer to stifle the scripts which overuse it. The problem is, prompt() appears to be the only way browser Javascript has of actually pausing a script to wait for input. If we avoid it, that throws us immediately into having to deal with a real-time GUI event input model.
I've been looking for a way to fake it -- to set up some kind of environment in which it is possible for a Javascript method to wait for input and then return when it's given. The best possibility I've got so far is to connect it to a Java applet, but the java applet brand is kind of poisoned now and I doubt people would want to install the plugin. Could there be another way? Worker threads? A browser add-on? Some server-side trick? Does anyone have an idea?
This question is now years old... I wonder if the addition of promises and async/await to Javascript makes this any more possible now?
...I sort of got it to work. If the read-eval-print loop is in an async function and uses await for the line that reads input, you can indeed make an old fashioned linear read-eval-print loop in an event-driven browser environment. But I don't think you can make the main thread wait on input without an async function, except with the grandfathered prompt method (which they're now getting ready to deprecate).
The technical term for what you want is a REPL: a Read-Evaluate-Print-Loop. There are many REPLs out there.
The Best Browser-Based Solution
Use Google Chrome's inbuilt console! It's a Javascript REPL that can also let you interact with a web page. You can access it by using Ctrl+Shift+I on Windows and Unix inside Chrome, or the equivalent command on a Mac (Google it!).
To load a file and play with it, all your students need to do is create a directory structure like this:
project
|--> index.html
|--> javascript.js
make sure index.html has a script tag that points to javascript.js, and then open index.html with Chrome. Voila! You have loaded a Javascript file, and can now play around with it in Chrome.
It's the best solution because you get the full power of the DOM, can do REPL stuff, and is virtually painless - everyone uses Chrome, and your students can even go home and mess around with it completely.
A Browser-Based Alternative
Rather than reinvent the wheel, you can also use Repl.it.
It's a browser-based Javascript REPL website that supports inserting an arbitrary Javascript program, and interacting with its contents. This is the closest you'll probably get to meeting your requirements - it'll be unable to interact with the DOM (obviously), but it'll more than work.
Non-Browser-Based Alternative
If the requirement for a web-based solution can be relaxed, simply using Node.js' inbuilt REPL on a terminal can be more than sufficient.
You could install Node on your lab's computers, and have people play with Javascript in that capacity. There'll be no DOM, but you could certainly have them write functions and algorithms to solve simple problems. Plus, it'd be a good way to introduce them to the fact that Javascript is no longer client-side-bound.
The fact that you'll be interacting with Javascript in an actual terminal, rather than an emulated one in the browser, is another neat bonus.
If I've Misunderstood...
Some of the question comments make it sound like you want a way to be able to interact with terminal utilities using Javascript from a browser. If that is the case, this is impossible.
There is no way for Javascript to evaluate, parse or do anything on the command line that isn't written using Javascript. You cannot expect the equivalent of a bash ls using a browser-based solution - that's because browsers don't have access to your underlying filesystem, which is a good thing. You cannot run sed, awk, grep, etc. for the same reason - Unix utilities are inaccessible to a browser. There are ways to run Unix utilities using Node, of course, but then you will be teaching them how to use Node, rather than how to play with the Unix console.
If all you want, however, is a way to SSH from a browser into a common environment, there are certainly browser-based ways to do that. FireSSH is a Firefox plugin (now also ported to Chrome) that lets people SSH into a common server. They can then do ls, vim, etc. and have it run in the server, with the results piped back to their browser screen. You'll have to think carefully about security in this case, of course, but I think simply giving people user permissions for this server should more than suffice.
Note that FireSSH doesn't use Javascript to parse or do anything - all it is doing is relaying commands you type to a server, having the server execute those commands remotely, and then piping the results back to your screen.
Alternatives to Prompt
I added this after understanding OP's requirements in more detail.
This is a question that has been asked before. I am fond of library solutions, and in 2013, iocream.js was developed for just this sort of browser functionality. You can embed it in a page, and use the jin function to assign values.
If going with a Node.js solution, by far the best approach is to make use of the prompt library. I personally find it very useful for embedding within Node.js applications.
SpiderMonkey is Mozilla's C++-based Javascript engine, and supports a function called readline(). Unfortunately, there doesn't appear to be a mainstream browser implementation.

What happens to JavaScript code after app is compiled using Titanium Mobile

I installed Titanium from appcelerator and built the "KitchenSink" example application.
All works well, I'm just wondering where does the javascript code ends up in a built app.
I grep-ed the Xcode project and also the result application as I found it in Library/Application Support/iPhone Simulator/....KitchenSink.app, but I can't find any function names from .js files, not even string texts used within the application.
Nearest information I found is an answer here : How Does Appcelerator Titanium Mobile Work? but I do not understand clearly how the process works.
Is the javascript code being compiled into a binary code (what compiler is used then?), or is it just transformed in some special data-format and interpreted in a running application ?
Update:
This is what I can see in a build/android directory of KitchenSink:
michal:bin mac$ find . -name table_view_layout\*
./assets/Resources/examples/table_view_layout.js
./assets/Resources/examples/table_view_layout_2.js
./assets/Resources/examples/table_view_layout_3.js
./assets/Resources/examples/table_view_layout_4.js
./assets/Resources/examples/table_view_layout_5.js
./classes/org/appcelerator/generated/examples/table_view_layout.class
./classes/org/appcelerator/generated/examples/table_view_layout_2.class
./classes/org/appcelerator/generated/examples/table_view_layout_3.class
./classes/org/appcelerator/generated/examples/table_view_layout_4.class
./classes/org/appcelerator/generated/examples/table_view_layout_5.class
michal:bin mac$ unzip -t app.apk | grep table_view_layout
testing: assets/Resources/examples/table_view_layout.js OK
testing: assets/Resources/examples/table_view_layout_2.js OK
testing: assets/Resources/examples/table_view_layout_3.js OK
testing: assets/Resources/examples/table_view_layout_4.js OK
testing: assets/Resources/examples/table_view_layout_5.js OK
I didn't look into app.apk before, all I could see were these class files corresponding to each of the javascript files. Therefore I assumed that on Android javascript is being compiled for JVM. Why can't these be found in app.apk ?
Titanium is not a wrapper around a web view as stated before (though that accurately explains how Phonegap works). Jeff's answer, linked in the question, is a technically correct explanation of how Titanium works, but here's the best version I've heard so far, from Marshall Culpepper:
It's true that Titanium Mobile used the WebView (in both Android and iOS) in the pre-1.0 days. However, this is no longer true and hasn't been since our 1.0 release is March 2010.
Since 1.0, we've shipped two separate Javascript runtimes with our apps, and we are running the Javascript code directly without a WebView. Your entire app from start to finish is now controlled by JS, and we provide a comprehensive set of Native APIs that enable this. Everything from UI widgets (yes, including WebView), Core APIs like Networking, Filesystem, Database, all the way to OS-specific things like JS Activities in Android. On the JS runtime front, we're shipping a forked version of WebKit's JavaScriptCore in iOS and a snapshot of Rhino 1.7 R3 CVS for Android. What we actually do with your javascript source is dependent on the platform, but generally it breaks up like this:
Source is statically analyzed to find references to Titanium modules
Localization strings (strings.xml), App metadata (tiapp.xml), and density specific images all generate platform specific analogs.
In iOS:
An XCode project / configuration is generated
JS Source is base64'd and inlined as a variable into a generated C file
xcodebuild is used to generate the final binaries
provisioning profiles, signing keys etc are applied
iTunes and some other glue are used to send the IPA to your iOS device
In Android:
An Android / Eclipse project is generated
In "Development" mode, JS source is packaged as APK assets
In "Distribution" (production) mode, when you're ready to ship the app, we compile the JS to Java bytecode using the Rhino JSC compiler. You can also enable this during development mode by setting "ti.android.compilejs" to "true" in tiapp.xml, see: http://developer.appcelerator.com/question/100201/enable-android-byte-code-compile
dex, aapt, and other Android SDK tools are used to build and generate the final APK
adb and keytool are used for pushing the APK out to the emulator and/or device
There are many more details that I could dive into specifically on each of these points, but the point I wanted to drive home is that we no longer use the WebView as our Javascript engine. You can however still embed WebViews, and we provide some simple integration that allows you to call Titanium APIs from an embedded WebView.
What jhaynie is saying in your linked question is that Titanium interprets your JS code and converts it into something that is almost identical to Objective-C.
In a web application, the browser reads and interprets your Javascript and runs associated native code (perhaps C++) internally. For instance, the browser might say, "This script is executing getElementById(), so I'll run my own C++ methods to accomplish that." What Titanium is doing is figuring out what that JS->C++ (or in this case, JS->Objective-C) would be in advance, and compiling that. It still leaves an interpreter open where necessary for your dynamic code, but it will convert and compile what it can.
That means you won't find anything that looks similar to what you originally wrote in your script. Anything that must be left to an interpreter is still processed and converted, and your symbols will change (e.g. a call to myTestFunction() might be converted to A(), or 10001101001101 :P).
The usual use of Javascript is to have it interpreted real-time by a running program. That's not what's going on here, and that's why you can't see any trace of your script.
Javascript is pre-processed
Titanium performs the interpretation of your script as any other program would do (such as a web browser). It figures out what dependencies your script has on the Titanium API and sets that stuff up. It then maps your symbols directly into (in the case of the iPhone) Objective-C.
A program usually would read in your script (which is a simply a String), interprets it, and runs C code to accomplish what your script asked for. Titanium does this before-hand to figure out what C code should be run, and does the conversion in advance.
Code is compiled where possible
Based on the interpretation of your code and its dependencies on the Titanium API, Titanium figures out what code can be directly compiled, and what must not be compiled in order to allow for they full dynamics of Javascript. I don't know how it chooses what does and doesn't get compiled, but you could check out the source if you want to know that much detail.
Code that must still be interpretted (left as a script) is still converted into symbols that result in more efficient mapping to native code. So it's still an interpreted script, but that doesn't mean it's still Javascript. This means that these parts of your script will still run faster than usual Javascript.
For iPhone, the compilable C is compiled with GCC to create a native binary.
You have a runnable app*
Now you have an app that you can run on your mobile device. Your compilable code has been compiled and runs at lightning speed, while the rest is converted and still interpreted in a more efficient way which runs at near lightning speed. :P
I hope this makes sense now, because it's all I've got! :D

How do I run a system command in a cydget using objective c or javascript?

I am trying to run a Ruby script from a cydget (cydget is a framework made by Saurik for writing lockscreens on the iPhone, using cycript, which is a mix of javascript & objc - see http://www.cycript.org/ ) The script will first check to see if a WEBrick server is running, if so it will quietly exit, if not it will start the server.
Apparently the iPhone doesn't support NSTask, and I don't know if the cycript implementation of obj-c does or not. (To be honest, I have no clue how obj-c in cycript works at all!) I'm not worried about security, because I'm running 1 specific command: "ruby server.rb", and everything else will be handled through the web server itself.
Is there any way other than NSTask in objective-c, or any way in javascript or HTML that I can run an arbitrary command on the local machine?
Thank you!
Brent
You can't fork another process on an iPhone at all (assuming we're talking about a legitimate app developed against Apple's official SDK). No NSTask, no fork()/exec(), no system(), nothing.
So it sounds like the best solution is to just wait - Saurik will be coming out with a way of directly using Ruby in a cydget, but it likely won't be out for a few months... :( I hope it will be worth the wait though!

Building v8 without JIT

I would like to run some tests on v8 with and without JIT to compare
performances.
I know JIT will improve my average speed performance, but it would be
nice for me to have some actual more detailed tests results as I want to work with mobile platforms.
I haven't found how to enable or disable JIT like it exists on Squirrelfish (cf. ENABLE_JIT in JavaScriptCore/wtf/Platform.h).
Does somebody knows how to do that with v8?
Thanks.
Alexandre
For those who may be interested I got the following answer from Søren Gjesse on v8-users google groups.
Hi,
It is not possible to disable dynamically generated code in V8. Unlike other
JavaScript engines V8 does not have an interpreter mode - it always
generates native code.
One exception is the RegExp engine which have an interpreter and native code
version. The compile time define V8_NATIVE_REGEXP enables generating native
code for RegExp processing.
Regards,
Søren
On a 32 bit little endian platform you can build with the ARM simulator. This is a testing feature and performance will be terrible, but it does work and involves no direct execution of JITed code. Use the --simulator=arm option on the scons or test.py command line.

Categories

Resources