To register for the beta program and download the Intel® HTML5 App Porter Tool – BETA click the button below.
(Version: 0.5.4137.79)
Please, download the tutorial sample app before starting this tutorial.
Introduction
This tutorial helps you use the Intel® HTML5 App Porter Tool – BETA to port a native Apple 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 like the original code as possible.
Objectives
Use this tutorial to:
- 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. The original Balloon Ninja iOS app uses JSONKit as a third-party API for persistence. It also uses Apple NSFoundation, UIKit framework, and Audio Toolbox as native APIs. For this tutorial app, the Intel® HTML5 App Porter Tool – BETA converts about 80% of the native APIs, because most common features in NSFoundation and UIKit are supported.
See a screenshot of the original application running in the iOS* simulator, below.
From Apple 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 and finish the porting process to get a converted (translated) HTML5 version of this 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 for both the source and destination folders.
Step 2 - Selecting the modules to be processed
In this step, uncheck the JSONKit.m
file to exclude it from the translation process. Because JavaScript* has native support with JSON, the best approach is not to translate that library, but to rewrite the JSON management using JavaScript.
Note: Carefully selecting the classes to translate is a key step. As a general criteria, avoid translating any modules in the original app that implement functionality that is already supported in JavaScript. Additionally, avoid translating modules that are implemented using low-level features of C or Apple Objective-C* that may be translated to JavaScript rather unnaturally.
In this case, uncheck the JSONKit/JSONKit.m line below because it uses C low-level features that are not fully supported.
The checkbox on the bottom of this screen lets you 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 shown in the images below. Otherwise, you can choose to ignore (skip) the files that cannot be parsed. After editing or ignoring those files, you can continue to Step 4. In case 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 can decide which methods to convert based on the API Coverage shown in the columns on the right.
Uncheck the interface LeaderboardManager
because the JSON serialization will be re-done directly in JavaScript.
After you click Next, the following screen will appear. Please, wait until all API calls have been processed.
Additionally, in the following screen, you can choose whether to generate an Intel® XDK zip bundle, or a Microsoft Visual Studio* 2012 project file. By default, both are generated.
Step 5 - Reading the results
After the translation completes, carefully read the "Translation Report" and the "TODO Report" available on the final screen, or in the TranslationReports
folder of the translated application:
- The Translation Report shows some details of the translation itself, such as the mapping between
.m
and.js
files. - The TODO Report provides the list of files that represent the template declarations for the APIs that were not mapped to equivalent HTML5 code.
Use these reports to help you complete porting your original app and create 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 Project Folder to open the folder where the translated application code is located. There, you can either follow the instructions in intel_xdk_package\upload_instructions.txt file to import the translated code into Intel® XDK, or navigate to the src folder and click over the .jsproj file to open the translated HTML5 code in Microsoft Visual Studio* (if available).
Once you open the translated code, you should 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 not able to translate.
6.1. Implement Audio APIs
Open pendingAPIcallsToPort\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
.
play: function() { var that = this; setTimeout(function(){ that._audio.play(); }, 0); }, initWithContentsOfURL_error: function(url1, arg2) { // parameter url1 is of type HTMLAnchorElement this._audio = new Audio(url1.href); return this; },
6.2. 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 Classes\LeaderboardManager.js
and replace the code for functions leaderboard
, addScore_name
, saveData
and getData
with the one provided below.
application.LeaderboardManager.leaderboard = function() { return application.LeaderboardManager.getData("leaderboard"); }; application.LeaderboardManager.addScore_name = function(score, name) { var leaderboard = application.LeaderboardManager.leaderboard(); var scoreDic = new APT.Dictionary(); scoreDic[new String("name")] = name; scoreDic[new String("score")] = score; leaderboard.push(scoreDic); leaderboard = leaderboard.sort(function (a, b) { if (a.score > b.score) return -1; if (a.score < b.score) return 1; return 0; }); var leaderboardDictionary = { "leaderboard": leaderboard }; var leaderboardString = JSON.stringify(leaderboardDictionary); application.LeaderboardManager.saveData("leaderboard", leaderboardString); }; application.LeaderboardManager.saveData = function (name, data) { localStorage[name] = data; return true; }; application.LeaderboardManager.getData = function (name) { var data = localStorage[name]; if (data == null) { return new Array(); } else { var jsonVar = JSON.parse(data); for (var i = 0; i < jsonVar.leaderboard.length; i++) { jsonVar.leaderboard[i] = new APT.Dictionary().initWithDictionary(jsonVar.leaderboard[i]); } return jsonVar.leaderboard; } };
6.3. Re-factor dynamic calls
Open the file Classes\LeaderboardViewController.js
and look into the function tableView_cellForRowAtIndexPath
to remove the call integerValue():
/* call to 'integerValue()' removed */ 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.4. 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.
The current 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 Classes\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.
div#Label_934540285 { text-align: right; width: 54px; height: 21px; position: absolute; left: 14px; opacity: 1; top: 116px; /* new attribute color added */ color: white; } div#Label_760896869 { text-align: left; width: 105px; height: 23px; position: absolute; left: 168px; opacity: 1; top: 54px; /* new attribute color added */ color: white; }
To make the code more readable, you can change the 'id' attribute in the .html file. But you may need to also update the file xibboilerplatecode.js
. The numbers in the id attribute, are numbers used internally by .xib files in the original application.
Next, open the file BalloonNinjaViewController_View_XXXXX.css
and add properties to label's CSS selectors to make the font bold and bigger.
div#Label_88872199 { text-align: center; width: 55px; height: 37px; position: absolute; left: 133px; opacity: 1; top: 7px; color: rgba(255,246,6,1); /* change the font to be bold and 16pt*/ font-weight: bold; font-size: 16pt; } div#Label_397160484 { text-align: center; width: 114px; height: 37px; position: absolute; left: 206px; opacity: 1; top: 7px; color: rgba(0,255,74,1); /* change the font to be bold and 16pt*/ font-weight: bold; font-size: 16pt; }
The last file that you need to update is Classes\LeaderBoardViewController_View_XXXXX.css
. Open that file and set the TableView's property background-color
to transparent as shown below.
div#TableView_91620652 { /* change background color to transparent */ background-color: transparent; /* and change width from fixed size to relative */ width: 80%; height: 283px; position: absolute; left: 54px; opacity: 1; top: 80px; }
Now, you are ready to test your new HTML5 application by running the project in the Intel® XDK or the Windows 8* OS emulators. For example, read the readme.txt file in the output HTML5_Conversion
directory and locate the zip file (bundle) and upload instructions in the /intel_xdk_package
subdirectory.
Translated app running inside the Intel® XDK emulator
Translated app running in Windows 8* OS emulator from Microsoft* Visual Studio*
To register for the beta program and download the Intel® HTML5 App Porter Tool – BETA click the button below.
Resources
- Technical Reference - Intel® HTML5 App Porter Tool - BETA
- The HTML5 section of the Intel® Developer Zone at http://software.intel.com/html5
- The Intel® XDK at http://www.html5dev-software.intel.com