iOS / Android Native Extension

Mobile is an important part of the world around us ( we have a 3.8 billion smartphone users worldwide) - and they all use everyday mobile applications and games. But mobile has a less significant role in the Haxe ecosystem and definitely has a low adoption when it comes to native extension.

The reason for that could be :

  • missing an easy way to compile to Android / iOS directly in Haxe ( maybe with some part of SDL integration in new display package);
  • too many frameworks with different integration for native extension ;
  • too small community;
  • not many programmers work with Haxe and Java/Kotlin or Object-C/Swift.

Some time ago, there was one effort to bring many extensions in one place for different frameworks HaxeExtension ( Haxe Extensions · GitHub), but there were mostly OpenFL extensions,and not for other frameworks. Also, as you can see in the repository, there are no regular updates for the extensions.

On the other hand, @jeremyfa created one excellent tool for the automatic generation of iOS/Android bindings, but still, it is only used in Ceramic.

So I want to start an initiative for sharing more native Haxe extensions using the Bind for all frameworks - OpenFL, HaxeFixel, NME, Ceramic, and even in Heaps and Kha.
The idea here is to create an Android or an XCode project, create the binding files and write some instructions for integration.

For example for Android it may include build.gradle files, properties files, and so on.
After that, everyone can use it to integrate into the framework he uses.

Here is an example:

There is no active extension for Crashlytics . The last one ( extension-crashlytics (1.0.0)) uses Fabric SDK, which is not supported anymore. There is no updated extension, and even the old one maybe not work correctly for Android.

So, I created a separate Android project ( which can be used for tests directly in Android Studio ) and a sample project with OpenFL integration: GitHub - flashultra/ExtensionCrashlytics-Android
In the OpenFL project, you can find all the needed build.gradle files with short instructions for easy integration in any framework or copy/paste in your framework template system.
At the moment, It’s only for Android, but it can be integrated for iOS too.

The same could be done for in-app-purchase extension, push notification extension, AdMob , Facebook, Apple ID, and so on.

I think this will help anyone who wants to publish on a mobile platform and may even someday have a separate place ( at example extensions.haxe.org) for all native extensions for Haxe.

That’s a tricky subject for sure.

It would be nice to have a repository of native extensions for Haxe that work with all frameworks, but this seems quite difficult to achieve.

For instance, my utility (bind), does not account for Hashlink used with iOS or Android. It’s specific to Haxe/C++ target. (It could be improved to work with HL too, but that’s a great load of work to do, which I won’t put myself into as I don’t use HL at the moment). Bind also solves only one part of the problem. The way files are integrated in the final project is specific to each framework.

That said, I believe having ios or android extensions that are self contained projects (gradle / xcode) that then could be bound to different frameworks is a good direction. I also think that taking advantage of tools like Cocoapods (that’s what I use with ceramic on iOS) could simplify how native (objc/swift) files are integrated into the final Xcode project. Android projects already have gradle to easily manage dependencies, Cocoapods bring a similar solution to iOS and seems mandatory to me.

I guess a good first step would be to create a framework agnostic library (like the crashlytics one you provided) that can work with most haxe frameworks that target ios/android. Not an easy task though. I am actually using crashlytics for iOS and Android with a ceramic project, but did not set it up as a separate library. Maybe at some point I will try…

It will definitely not be possible to make a implementation for all frameworks, and I think that should not be the goal .
The main idea will be to have a separate project for each extension, and from the main class ( classes) the Bind could create the stub classes.
After that, the implementation will be different for each framework, and someone who use that framework should do the integration ( with all dependencies).
Here I agree that Cocoapods should be mandatory for Xcode projects

What is the advantage of this approach?

  1. The native code ( Java ,Swift) can be written only once and the contrubutor will work on this project as separate one
  2. Easy ( auto) binding of the native code with the Haxe .
  3. If someone wants to try another framework, it will be much easier, because there will be native extensions

Cons:

  1. There is no C/Hashlink binding
  2. Someone should need to do the first step of integration of Bind in the framework which he use.
  3. The framework should support some structure for integration of the specific file for the extension ( gradle files, etc)

At the moment I don’t know how Ceramic use native exetnsions , I could’n find anything in Ceramic repository ( Ceramic · GitHub ) and this could be a stopper for someone who want to use it. This is valid for all frameworks and is a kind of a warning before you start ( Unity for example have built-in In app purchase package )

In ceramic, you can directly from your ceramic project’s ceramic.yml file add native ObjC or java code by simply referencing the files:

app:

    ...

    if ios:
        +bind:
            - SomeHeaderToObjcClass.h
            - SomeOtherHeaderToObjcClass.h

    if android:
        +bind:
            - my/java/dir/SomeJavaClass.java
            - my/java/dir/SomeOtherJavaClass.java

The same thing can be done encapsulated into a ceramic plugin (which also have its own ceramic.yml file).

At the moment I didn’t publish any native extension for ceramic, although I did implement things like in-app purchase or crashlytics already so I could consider publishing that code at some point.

1 Like