http://software.intel.com/en-us/articles/tutorial-creating-an-html5-app-from-a-native-ios-project-with-intel-html5-app-porter-tool
Introduction
The main goal of this tutorial is to help you use the Intel® HTML5 App Porter Tool – BETA to port a native iOS* app to HTML5. The Intel® HTML5 App Porter Tool – BETA will generate clean and easy to read code, keeping the auto-generated code as much alike the original as possible.
Objectives
With this document you will:
- Learn how to configure the tool to get the best results possible
- Understand the feedback provided by the tool
- Learn how to finish the translation process by completing the portions of code that could not be translated by the tool
Tutorial Example - “Balloon Ninja”
Balloon Ninja is a mini game where you get points by popping balloons. The more balloons you pop in a minute, the more points you get. It uses JSONKit as third party API for persistence. It also uses NSFoundation, UIKit and Audio Toolbox as native API. For this tutorial app, the Intel® HTML5 App Porter Tool – BETA will have about 80% of API translation rate, as most common features in NSFoundation and UIKit are supported.
See a screenshot of the original application running in the iOS* simulator, below.
From iOS* to HTML5 in just 6 steps
This section shows the different steps that you need to follow to successfully run the Intel® HTML5 App Porter Tool – BETA, finish the porting process and get a translated HTML5 version of the sample app.
Step 1 - Setting the project and output paths
Select the project to translate, in this case Balloon Ninja, and the destination path. For the source path, select the .xcodeproj
folder, otherwise you will get an error message saying “This is not a valid Xcode* Project”. Please, make sure that you have write permissions on both the source and destination folders.
Step 2 - Selecting the modules to be processed
In this step, unselect the JSONKit.m
file to exclude it from the translation process. As JavaScript has a native support with JSON, the best approach here is not to translate that library altogether but to rewrite the JSON management using JavaScript support.
Note: Carefully selecting the classes to translate is a key step. As a general criteria, you should avoid translating any modules in the original app that implement a functionality that is already supported in JavaScript. Additionally, you may also avoid translating modules that are implemented using low level features of C or Objective-C* that may be translated to JavaScript rather unnaturally.
The checkbox on the bottom of the screen above allows you to add missing include folders or preprocessor directives, if necessary.
In this case, no additional configuration is necessary since the JSONKit sources are already included as a part of the project. However, if the parsing process fails, this is where you should add any API or framework headers that are not included on the project. These errors could be caused by a third party library outside the project folder or a missing preprocessor directive, such as preprocessor definitions for DEBUG
or RELEASE
, or any #define
that should be set manually.
Step 3 - Parsing modules
During this step, Intel® HTML5 App Porter Tool – BETA attempts to parse the project and determines the part of the code that can be translated. If the tool is unable to parse a file, it will allow you to fix issues by editing the files that could not be parsed, as it is shown in the images below. Otherwise, you can choose to ignore (i.e., skip) the files that cannot be parsed. After editing or ignoring those files, you can continue to Step 4. In case that you encounter no parsing issues, you will see the sequence of screens, below.
Step 4 - Select the methods to be translated
Finally, after parsing and analyzing the entire project, the result
is shown in a simple report. You will be able to decide which methods to
translate based on the API coverage shown in the columns on the right.
Unselect the interface LeaderboardManager
as JSON serialization will be re-done directly in JavaScript.
Step 5 - Reading the results
After the translation is completed, it is highly recommended to look
into the "Translation Report" and the "ToDo Report" available on the
final screen and also located in the TranslationReports
folder of the translated application. The former shows some details of the translation itself, such as the mapping between .m
and .js
files. The latter provides the list of files that represent the
template declarations for the APIs that were not mapped to equivalent
HTML5 code. This reports should guide you on what you need to complete
in order to have a working version of your HTML5 app.
Step 6 - Connecting the missing dots
The automatic translation phase performed by the tool is over. Now,
you should complete the porting of those APIs and features that were not
supported by the tool. Select Open Application to open Microsoft* Visual Studio* (if available, or open Open Project Folder,
otherwise), then you will be able to edit the JavaScript files. If you
look inside each ToDo JavaScript file, you will see methods throwing
exceptions and comments about where that function is being called in the
project. You need to complete the methods that the tool was unable to
translate.
6.1. Disable exceptions thrown by API placeholders
Remove all the exceptions thrown in API placeholders by adding the following line in main.js
.
1 |
APT.Global.THROW_IF_NOT_IMPLEMENTED = false ; |
6.2. Implement Audio APIs
Open todo_api_application_avaudioplayer.js
. You will see 4 methods to implement, but you only need to implement initWithContentsOfURL_error
and play
methods. Copy the code below to complete the implementation of initWithContentsOfURL_error
and play
.
04 |
setTimeout( function (){ |
09 |
initWithContentsOfURL_error: function (url1, arg2) { |
11 |
this ._audio = new Audio(url1.href); |
6.3. Implement JSON serialization
Because JavaScript provides native support to deal with JSON it is
better to provide new implementations for serialization directly in
JavaScript. Here we use HTML5 localStorage API to implement the
persistence.
Open the file leaderboardmanager.js
and replace the code for functions leaderboard
, addScore_name
, saveData
and getData
with the one provided below.
01 |
application.LeaderboardManager.leaderboard = function () { |
02 |
return application.LeaderboardManager.getData( "leaderboard" ); |
05 |
application.LeaderboardManager.addScore_name = function (score, name) { |
06 |
var leaderboard = application.LeaderboardManager.leaderboard(); |
08 |
var scoreDic = new APT.Dictionary(); |
09 |
scoreDic[ new String( "name" )] = name; |
10 |
scoreDic[ new String( "score" )] = score; |
11 |
leaderboard.push(scoreDic); |
13 |
leaderboard = leaderboard.sort( function (a, b) { |
14 |
if (a.score > b.score) return -1; |
15 |
if (a.score < b.score) return 1; |
19 |
var leaderboardDictionary = { "leaderboard" : leaderboard }; |
20 |
var leaderboardString = JSON.stringify(leaderboardDictionary); |
21 |
application.LeaderboardManager.saveData( "leaderboard" , leaderboardString); |
24 |
application.LeaderboardManager.saveData = function (name, data) { |
25 |
localStorage[name] = data; |
29 |
application.LeaderboardManager.getData = function (name) { |
30 |
var data = localStorage[name]; |
36 |
var jsonVar = JSON.parse(data); |
37 |
for ( var i = 0; i < jsonVar.leaderboard.length; i++) |
39 |
jsonVar.leaderboard[i] = new APT.Dictionary().initWithDictionary(jsonVar.leaderboard[i]); |
41 |
return jsonVar.leaderboard; |
6.4. Re-factor dynamic calls
Open the file leaderboardviewcontroller.js
and look into the function tableView_cellForRowAtIndexPath
to remove the call integerValue()
like in the code below.
2 |
cell.detailTextLabel().setText(APT.Global.sprintf( new String( "%i" ), scoreDic.objectFor( new String( "score" )))); |
The call to integerValue()
is not translated by the tool
(in JavaScript is not needed) because it is a dynamic message to a
generic Objective-C object. Current version of the tool does not support
API translation of dynamic messages. Because of that, it is recommended
to provide type information for all variables and temporal values in
your original source code before running the translation.
6.5. Tweak CSS files
In the next step, you will change properties in generated CSS files.
The tool generates a pair of .html and .css file for each view found in
translated .xib files.
Current version of the tool does not support all of the properties or
kind of values available in .xib files. For some labels, the sample use
other color spaces that are not RGB. Those color properties are not
translated and we need to update the generated code.
Open the file WriteScoreViewController_View_XXXXXX.css
(the number at the end is not important) file and for each div#Label with a missing color:
property add a new line "color: white;
". See the example below.
To make the code more readable, you can change the 'id' attribute in
the .html file. But take into account that you may also need to update
the file xibboilerplatecode.js
. The numbers in the id
attribute, are numbers used internally by .xib files in the original
application. In further updates of the tool you will see more user
friendly ids.
Next, open the file BalloonNinjaViewController_View_XXXXX.css
and add properties to label's CSS selectors to make the font bold and bigger.
10 |
color : rgba( 255 , 246 , 6 , 1 ); |
26 |
color : rgba( 0 , 255 , 74 , 1 ); |
The last file that you need to update is LeaderBoardViewController_View_XXXXX.css
. Open that file and set the TableView's property background-color
to transparent color like shown below.
01 |
div#TableView_ 91620652 |
04 |
background-color : transparent ; |
Now, you are ready to test your new HTML5 application by running the project in the Windows 8* emulator.
To register for the beta program and download the Intel® HTML5 App Porter Tool – BETA click the button below.
Sign up and Download
Requires Windows* 8 and Microsoft* Visual Studio* 2012