Introduction
The Intel® HTML5 App Porter Tool - BETA is an application that helps mobile application developers to port native iOS* code into HTML5, by automatically translating portions of the original code into HTML5. This tool is not a complete solution to automatically port 100% of iOS* applications, but instead it speeds up the porting process by translating as much code and artifacts as possible.
It helps in the translation of the following artifacts:
- Objective-C* (and a subset of C) source code into JavaScript
- iOS* API types and calls into JavaScript/HTML5 objects and calls
- Layouts of views inside Xcode* Interface Builder (XIB) files into HTML + CSS files
- Xcode* project files into Microsoft* Visual Studio* 2012 projects
This document provides a high-level explanation about how the tool works and some details about supported features. This overview will help you determine how to process the different parts of your project and take the best advantage from the current capabilities.
How does it work?
The Intel® HTML5 App Porter Tool - BETA is essentially a source-to-source translator that can handle a number of conversions from Objective-C* into JavaScript/HTML5 including the translation of APIs calls. A number of open source projects are used as foundation for the conversion including a modified version of Clang front-end, LayerD framework and jQuery Mobile* for widgets rendering in the translated source code.
Translation of Objective-C* into JavaScript
At a high level, the transformation pipeline looks like this:
This pipeline follows the following stages:
- Parsing of Objective-C* files into an intermediate AST (Abstract Syntax Tree).
- Mapping of supported iOS* API calls into equivalent JavaScript calls.
- Generation of placeholder definitions for unsupported API calls.
- Final generation of JavaScript and HTML5 files.
About coverage of API mappings
Mapping APIs from iOS* SDK into JavaScript is a task that involves a good deal of effort. The iOS* APIs have thousands of methods and hundreds of types. Fortunately, a rather small amount of those APIs are in fact heavily used by most applications. The graph below conceptually shows how many APIs need to be mapped in order to have certain level of translation for API calls .
Currently, the Intel® HTML5 App Porter Tool - BETA supports the most used types and methods from:
- UIKit framework
- Foundation framework
Additionally, it supports a few classes of other frameworks such as CoreGraphics. For further information on supported APIs refer to the list of supported APIs.
Generation of placeholder definitions and TODO JavaScript files
For the APIs that the Intel® HTML5 App Porter Tool - BETA cannot translate, the tool generates placeholder functions in "TODO" files. In the translated application, you will find one TODO file for each type that is used in the original application and which has API methods not supported by the current version. For example, in the following portion of code:
-(void)sampleMethod { UIButton* myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [myButton setTitle:text forState:UIControlStateNormal]; myButton.showsTouchWhenHighlighted = YES; }
If property setter for showsTouchWhenHighligthed
is not supported by the tool, it will generate the following placeholder for you to provide its implementation:
APT.Button.prototype.setShowsTouchWhenHighligthed = function(arg1) { // ================================================================ // REFERENCES TO THIS FUNCTION: // line(108): SampleCode.m // In scope: Test.sampleMethod // Actual arguments types: [boolean] // Expected return type: [unknown type] // if (APT.Global.THROW_IF_NOT_IMPLEMENTED) { // TODO remove exception handling when implementing this method throw "Not implemented function: APT.Button.setShowsTouchWhenHighligthed"; } };
These placeholders are created for methods, constants, and types that the tool does not support. Additionally, these placeholders may be generated for APIs other than the iOS* SDK APIs. If some files from the original application (containing class or function definitions) are not included in the translation process, the tool may also generate placeholders for the definitions in those missing files.
In each TODO file, you will find details about where those types, methods, or constants are used in the original code. Moreover, for each function or method the TODO file includes information about the type of the arguments that were inferred by the tool. Using these TODO files, you can complete the translation process by the providing the placeholders with your own implementation for that API.
Translation of XIB files into HTML/CSS code
The Intel® HTML5 App Porter Tool - BETA translates most of the definitions in the Xcode* Interface Builder files (i.e., XIB files) into equivalent HTML/CSS code. These HTML files use JQuery* markup to define layouts equivalent to the views in the original XIB files. That markup is defined based on the translated version of the view classes and can be accessed programmatically.
Moreover, most of the events that are linked with handlers in the original application code are also linked with their respective handles in the translated version. All the view controller objects, connection logic between objects and event handlers from all translated XIB files are included in the XibBoilerplateCode.js
. Only one XibBoilerplateCode.js
file is created per application.
The figure below shows how the different components of each XIB file are translated.
This is a summary of the artifacts generated from XIB files:
- For each view inside an XIB file, a pair of HTML+CSS files is generated.
- Objects inside XIB files, such as Controllers and Delegates, and instantiation code are generated in the
XibBoilerplateCode.js
file. - Connections between objects and events handlers for views described inside XIB files are also implemented by generated code in the
XibBoilerplateCode.js
file.
For further information on supported widgets and properties refer to the Supported .XIB file featuressection.
Architecture of translated applications
The translated application keeps the very same high level structure as the original one. Constructs such as Objective-C* interfaces, categories, C structs, functions, variables, and statements are kept without significant changes in the translated code but expressed in JavaScript.
The execution of the Intel® HTML5 App Porter Tool – BETA produces a set of files that can be divided in four groups:
- The translated app code: These are the JavaScript files that were created as a translation from the original app Objective-C* files.
- For each translated module (i.e. each
.m
file) there should be a.js
file with a matching name. - The default.html file is the entry point for the HTML5 app, where all the other
.js
files are included. - Additionally, there are some JavaScript files included in the
\lib
folder that corresponds to some 3rd party libraries and Intel® HTML5 App Porter Tool – BETA library which implements most of the functionality that is not available in HTML5. - Translated
.xib
files (if any): For each translated.xib
file there should be.html
and.css
files with matching names. These files correspond to their HTML5 version. - “ToDo” JavaScript files: As the translation of some of the APIs in the original app may not be supported by the current version, empty definitions as placeholders for those not-mapped APIs are generated in the translated HTML5 app. This “ToDo” files contain those placeholders and are named after the class of the not-mapped APIs. For instance, the placeholders for not-mapped methods of the
NSData
class, would be located in a file named something liketodo_api_js_apt_data.js
ortodo_js_nsdata.js
. - Resources: All the resources from the original iOS* project will be copied to the root folder of the translated HTML5 app.
The generated JavaScript files have names which are practically the same as the original ones. For example, if you have a file called AppDelegate.m
in the original application, you will end up with a file called AppDelegate.js
in the translated output. Likewise, the names of interfaces, functions, fields, or variables are not changed, unless the differences between Objective-C* and JavaScript require the tool to do so.
In short, the high level structure of the translated application is practically the same as the original one. Therefore, the design and structure of the original application will remain the same in the translated version.
About target HTML5 APIs and libraries
The Intel® HTML5 App Porter Tool - BETA both translates the syntax and semantics of the source language (Objective-C*) into JavaScript and maps the iOS* SDK API calls into an equivalent functionality in HTML5. In order to map iOS* API types and calls into HTML5, we use the following libraries and APIs:
- The standard HTML5 API: The tool maps iOS* types and calls into plain standard objects and functions of HTML5 API as its main target. Most notably, considerable portions of supported Foundation framework APIs are mapped directly into standard HTML5. When that is not possible, the tool provides a small adaptation layer as part of its library.
- The jQuery Mobile library: Most of the UIKit widgets are mapped jQuery Mobile widgets or a composite of them and standard HTML5 markup. Layouts from XIB files are also mapped to jQuery Mobile widgets or other standard HTML5 markup.
- The Intel® HTML5 App Porter Tool - BETA library: This is a 'thin-layer' library build on top of jQuery Mobile and HTML5 APIs and implements functionality that is no directly available in those libraries, including Controller objects, Delegates, and logic to encapsulate jQuery Mobile widgets. The library provides a facade very similar to the original APIs that should be familiar to iOS* developers. This library is distributed with the tool and included as part of the translated code in the
lib
folder.
You should expect that future versions of the tool will incrementally add more support for API mapping, based on further statistical analysis and user feedback.
Translated identifier names
In Objective-C*, methods names can be composed by several parts separated with colons (:) and the methods calls interleaved these parts with the actual arguments. Since that peculiar syntactic construct is not available in JavaScript, those methods names are translated by combining all the methods parts replacing the colons (:) with underscores (_). For example, a function called initWithColor:AndBackground:
is translated to use the name initWithColor_AndBackground
Identifier names, in general, may also be changed in the translation if there are any conflicts in JavaScript scope. For example, if you have duplicated names for interfaces and protocol, or one instance method and one class method that share the same name in the same interface. Because identifier scoping rules are different in JavaScript, you cannot share names between fields, methods, and interfaces. In any of those cases, the tool renames one of the clashing identifiers by prepending an underscore (_) to the original name.
Additional tips to get the most out of the Intel® HTML5 App Porter Tool – BETA
Here is a list of recommendations to make the most of the tool.
- Keep your code modular
Having a well-designed and architected source code may help you to take the most advantage of the translation performed by tool. If the modules of the original source code can be easily decoupled, tested, and refactored the same will be true for the translated code. Having loosely coupled modules in your original application allows you to isolate the modules that are not translated well into JavaScript. In this way, you should be able to simply skip those modules and only select the ones suitable for translation. - Avoid translating third party libraries source code with equivalents in JavaScript
For some iOS* libraries you can find replacement libraries or APIs in JavaScript. Common examples are libraries to parse JSON, libraries to interact with social networks, or utilities libraries such as Box2D* for games development. If your project originally uses the source code of third party library which has a replacement version in JavaScript, try to use the replacement version instead of translated code, whenever it is possible. - Isolate low level C or any C++ code behind Objective-C* interfaces: The tool currently supports translating from Objective-C*, only. It covers the translation of most of C language constructs, but it does not support some low level features such as unions, pointers, or bit fields. Moreover, the current version does not support C++ or Objective-C++* code. Because of this limitation, it is advisable to encapsulate that code behind Objective-C* interfaces to facilitate any additional editing, after running the tool.
In conclusion, having a well-designed application in the first place will make your life a lot easier when porting your code, even in a completely manual process.
Further technical information
This section provides additional information for developers and it is not required to effectively use Intel® HTML5 App Porter Tool - BETA. You can skip this section if you are not interested in implementation details of the tool.
Implementation of the translation steps
Here, you can find some high level details of how the different processing steps of the Intel® HTML5 App Porter Tool - BETA are implemented.
Objective-C* and C files parsing
To parse Objective-C* files, the tool uses a modified version of clang parser. A custom version of the parser is needed because:
- iOS* SDK header files are not available.
- clang is only used to parse the source files (not to compile them) and dump the AST to disk.
The following picture shows the actual detailed process for parsing .m and .c files:
Missing iOS* SDK headers are inferred as part of the parsing process. The header inference process is heuristic, so you may get parsing errors, in some cases. Thus, you can help the front-end of the tool by providing forward declaration of types or other definitions in header files that are accessible to the tool.
Also, you can try the "Header Generator" module in individual files by using the command line. In the binary folder of the tool, you will find an executable headergenerator.exe
that rubs that process.
Objective-C* language transformation into JavaScript
The translation of Objective-C* language into JavaScript involves a number of steps. We can divide the process in what happens in the front-end and what is in the back-end.
Steps in the front-end:
- Parsing .m and .c into an XML AST.
- Parsing comments from .m, .c and .h files and dumping comments to disk.
- Translating Clang AST into Zoe AST and re-appending the comments.
The output of the front-end is a Zoe program. Zoe is an intermediate abstract language used by LayerD framework; the engine that is used to apply most of the transformations.
The back-end is fully implemented in LayerD by using compile time classes of Zoe language that apply a number of transformations in the AST.
Steps in the back-end:
- Handling some Objective-C* features such as properties getter/setter injection and merging of categories into Zoe classes.
- Supported iOS* API conversion into target JavaScript API.
- Injection of not supported API types, or types that were left outside of the translation by the user.
- Injection of dummy methods for missing API transformations or any other code left outside of the translation by the user.
- JavaScript code generation.
iOS* API mapping into JavaScript/HTML5
The tool supports a limited subset of iOS* API. That subset is developed following statistical information about usage of each API. Each release of the tool will include support for more APIs. If you miss a particular kind of API your feedback about it will be very valuable in our assessment of API support.
For some APIs such as Arrays and Strings the tool provides direct mappings into native HTML5 objects and methods. The following table shows a summary of the approach followed for each kind of currently supported APIs.
Framework | Mapping design guideline |
Foundation | Direct mapping to JavaScript when possible. If direct mapping is not possible, use a new class built over standard JavaScript. |
Core Graphics | Direct mapping to Canvas and related HTML5 APIs when possible. If direct mapping is not possible, use a new class built over standard JavaScript. |
UIKit Views | Provide a similar class in package APT, such as APT.View for UIView, APT.Label for UILabel, etc. All views are implemented using jQuery Mobile markup and library. When there are not equivalent jQuery widgets we build new ones in the APT library. |
UIKit Controllers and Delegates | Because HTML5 does not provide natively controllers or delegate objects the tool provides an implementation of base classes for controllers and delegates inside the APT package. |
Direct mapping implies that the original code will be transformed into plain JavaScript without any type of additional layer. For example,
NSArray * anArray = [NSArray arrayWithObjects:@"One",@"Two",@"Three",nil]; // Is translated to JavaScript code: var anArray = ["One", "Two", "Three"];
The entire API mapping happens in the back-end of the tool. This process is implemented using compile time classes and other infrastructure provided by the LayerD framework.
XIB files conversion into HTML/CSS
XIB files are converted in two steps:
- XIB parsing and generation of intermediate XML files.
- Intermediate XML files are converted into final HTML, CSS and JavaScript boilerplate code.
The first step generates one XML file - with extension .gld - for each view inside the XIB file and one additional XML file with information about other objects inside XIB files and connections between objects and views such as outlets and event handling.
The second stage runs inside the Zoe compiler of LayerD to convert intermediate XML files into final HTML/CSS and JavaScript boilerplate code to duplicate all the functionality that XIB files provides in the original project.
Generated HTML code is as similar as possible to static markup used by jQuery Mobile library or standard HTML5 markup. For widgets that do not have an equivalent in jQuery Mobile, HTML5, or behaves differently, simple markup is generated and handled by classes in APT library.
For detailed information about the API translation support, go to: http://software.intel.com/en-us/articles/intel-html5-app-porter-tool-beta-api-mapping-support-version-053407.
To register for the beta program and download the Intel® HTML5 App Porter Tool – BETA click the button below.
Requires Windows* 8 and Microsoft* Visual Studio* 2012
* Other names and brands may be claimed as the property of others.