9 min read

In this article by Mohamed Taman, authors of the book JavaFX Essentials, we will learn how to develop a JavaFX, Apple has a great market share in the mobile and PC/Laptop world, with many different devices, from mobile phones such as the iPhone to musical devices such as the iPod and tablets such as the iPad.

(For more resources related to this topic, see here.)

It has a rapidly growing application market, called the Apple Store, serving its community, where the number of available apps increases daily. Mobile application developers should be ready for such a market.

Mobile application developers targeting both iOS and Android face many challenges. By just comparing the native development environments of these two platforms, you will find that they differ substantially.

iOS development, according to Apple, is based on the Xcode IDE (https://developer.apple.com/xcode/) and its programming languages. Traditionally, it was Objetive-C and, in June 2014, Apple introduced Swift (https://developer.apple.com/swift/); on the other hand, Android development, as defined by Google, is based on the Intellij IDEA IDE and the Java programming language.

Not many developers are proficient in both environments. In addition, these differences rule out any code reuse between the platforms.

JavaFX 8 is filling the gap for reusable code between the platforms, as we will see in this article, by sharing the same application in both platforms.

Here are some skills that you will have gained by the end of this article:

  • Installing and configuring iOS environment tools and software
  • Creating iOS JavaFX 8 applications
  • Simulating and debugging JavaFX mobile applications
  • Packaging and deploying applications on iOS mobile devices

Using RoboVM to run JavaFX on iOS

RoboVM is the bridge from Java to Objetive-C. Using this, it becomes easy to develop JavaFX 8 applications that are to be run on iOS-based devices, as the ultimate goal of the RoboVM project is to solve this problem without compromising on developer experience or app user experience.

As we saw in the article about Android, using JavaFXPorts to generate APKs was a relatively easy task due to the fact that Android is based on Java and the Dalvik VM.

On the contrary, iOS doesn’t have a VM for Java, and it doesn’t allow dynamic loading of native libraries.

Another approach is required. The RoboVM open source project tries to close the gap for Java developers by creating a bridge between Java and Objective-C using an ahead-of-time compiler that translates Java bytecode into native ARM or x86 machine code.

Features

Let’s go through the RoboVM features:

  • Brings Java and other JVM languages, such as Scala, Clojure, and Groovy, to iOS-based devices
  • Translates Java bytecode into machine code ahead of time for fast execution directly on the CPU without any overhead
  • The main target is iOS and the ARM processor (32- and 64-bit), but there is also support for Mac OS X and Linux running on x86 CPUs (both 32- and 64-bit)
  • Does not impose any restrictions on the Java platform features accessible to the developer, such as reflection or file I/O
  • Supports standard JAR files that let the developer reuse the vast ecosystem of third-party Java libraries
  • Provides access to the full native iOS APIs through a Java-to-Objective-C bridge, enabling the development of apps with truly native UIs and with full hardware access
  • Integrates with the most popular tools such as NetBeans, Eclipse, Intellij IDEA, Maven, and Gradle
  • App Store ready, with hundreds of apps already in the store

Limitations

Mainly due to the restrictions of the iOS platform, there are a few limitations when using RoboVM:

  • Loading custom bytecode at runtime is not supported. All class files comprising the app have to be available at compile time on the developer machine.
  • The Java Native Interface technology as used on the desktop or on servers usually loads native code from dynamic libraries, but Apple does not permit custom dynamic libraries to be shipped with an iOS app. RoboVM supports a variant of JNI based on static libraries.
  • Another big limitation is that RoboVM is an alpha-state project under development and not yet recommended for production usage.

RoboVM has full support for reflection.

How it works

Since February 2015 there has been an agreement between the companies behind RoboVM and JavaFXPorts, and now a single plugin called jfxmobile-plugin allows us to build applications for three platforms—desktop, Android, and iOS—from the same codebase.

The JavaFXMobile plugin adds a number of tasks to your Java application that allow you to create .ipa packages that can be submitted to the Apple Store.

Android mostly uses Java as the main development language, so it is easy to merge your JavaFX 8 code with it. On iOS, the situation is internally totally different—but with similar Gradle commands.

The plugin will download and install the RoboVM compiler, and it will use RoboVM compiler commands to create an iOS application in build/javafxports/ios.

Getting started

In this section, you will learn how to install the RoboVM compiler using the JavaFXMobile plugin, and make sure the tool chain works correctly by reusing the same application, Phone Dial version 1.0.

Prerequisites

In order to use the RoboVM compiler to build iOS apps, the following tools are required:

The first time you install Xcode, and every time you update to a new version, you have to open it once to agree to the Xcode terms.

Preparing a project for iOS

We will reuse the project we developed before, for the Android platform, since there is no difference in code, project structure, or Gradle build script when targeting iOS.

They share the same properties and features, but with different Gradle commands that serve iOS development, and a minor change in the Gradle build script for the RoboVM compiler.

Therefore, we will see the power of WORA Write Once, Run Everywhere with the same application.

Project structure

Based on the same project structure from the Android, the project structure for our iOS app should be as shown in the following figure:

JavaFX Essentials

The application

We are going to reuse the same application from the Phone DialPad version 2.0 JavaFX 8 application:

JavaFX Essentials

As you can see, reusing the same codebase is a very powerful and useful feature, especially when you are developing to target many mobile platforms such as iOS and Android at the same time.

Interoperability with low-level iOS APIs

To have the same functionality of natively calling the default iOS phone dialer from our application as we did with Android, we have to provide the native solution for iOS as the following IosPlatform implementation:

import org.robovm.apple.foundation.NSURL;
import org.robovm.apple.uikit.UIApplication;
import packt.taman.jfx8.ch4.Platform;
 
public class IosPlatform implements Platform {
 
@Override
public void callNumber(String number) {
   if (!number.equals("")) {
     NSURL nsURL = new NSURL("telprompt://" + number);
     UIApplication.getSharedApplication().openURL(nsURL);
   }
}
}

Gradle build files

We will use the Gradle build script file, but with a minor change by adding the following lines to the end of the script:

jfxmobile {
ios {
   forceLinkClasses = [ 'packt.taman.jfx8.ch4.**.*' ]
}
android {
   manifest = 'lib/android/AndroidManifest.xml'
}
}

All the work involved in installing and using robovm compilers is done by the jfxmobile plugin.

The purpose of those lines is to give the RoboVM compiler the location of the main application class that has to be loaded at runtime is, as it is not visible by default to the compiler.

The forceLinkClasses property ensures that those classes are linked in during RoboVM compilation.

Building the application

After we have added the necessary configuration set to build the script for iOS, its time to build the application in order to deploy it to different iOS target devices. To do so, we have to run the following command:

$ gradle build

We should have the following output:

BUILD SUCCESSFUL
 
Total time: 44.74 secs

We have built our application successfully; next, we need to generate the .ipa and, in the case of production, you have to test it by deploying it to as many iOS versions as you can.

Generating the iOS .ipa package file

In order to generate the final .ipa iOS package for our JavaFX 8 application, which is necessary for the final distribution to any device or the AppStore, you have to run the following gradle command:

gradle ios 

This will generate the .ipa file in the directory build/javafxports/ios.

Deploying the application

During development, we need to check our application GUI and final application prototype on iOS simulators and measure the application performance and functionality on different devices. These procedures are very useful, especially for testers.

Let’s see how it is a very easy task to run our application on either simulators or on real devices.

Deploying to a simulator

On a simulator, you can simply run the following command to check if your application is running:

$ gradle launchIPhoneSimulator 

This command will package and launch the application in an iPhone simulator as shown in the following screenshot:

JavaFX Essentials

DialPad2 JavaFX 8 application running on the iOS 8.3/iPhone 4s simulator

This command will launch the application in an iPad simulator:

$ gradle launchIPadSimulator 

Deploying to an Apple device

In order to package a JavaFX 8 application and deploy it to an Apple device, simply run the following command:

$ gradle launchIOSDevice 

This command will launch the JavaFX 8 application in the device that is connected to your desktop/laptop.

Then, once the application is launched on your device, type in any number and then tap Call.

The iPhone will ask for permission to dial using the default mobile dialer; tap on Ok. The default mobile dialer will be launched and will the number as shown in the following figure:

JavaFX Essentials

To be able to test and deploy your apps on your devices, you will need an active subscription with the Apple Developer Program. Visit the Apple Developer Portal, https://developer.apple.com/register/index.action, to sign up. You will also need to provision your device for development. You can find information on device provisioning in the Apple Developer Portal, or follow this guide: http://www.bignerdranch.com/we-teach/how-to-prepare/ios-device-provisioning/.

Summary

This article gave us a very good understanding of how JavaFX-based applications can be developed and customized using RoboVM for iOS to make it possible to run your applications on Apple platforms.

You learned about RoboVM features and limitations, and how it works; you also gained skills that you can use for developing.

You then learned how to install the required software and tools for iOS development and how to enable Xcode along with the RoboVM compiler, to package and install the Phone Dial JavaFX-8-based application on OS simulators.

Finally, we provided tips on how to run and deploy your application on real devices.

Resources for Article:


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here