As you see here one can perform native C/C++ method calls from Java code, thanks to JVM’s JNI. But how about performing calls of Swift methods? Is this possible or going to be possible (can be implemented in a reasonable time frame) as Swift becomes more popular?
I want to access Apple’s native API that is only accessible when one writes apps in either Objective-C or Swift. As the JVM is just being ported to ARMv8 (64-bit), I could also imagine the JVM as an alternative runtime for iOS apps in the future. But this might be the future... The present is: The JVM runs on Mac OS X and one can write apps for Mac OS X in Swift that can access some APIs that might be not accessible to Java apps in the same way.
Wright is a skilled worker (usually a maker or builder), such as a shipwright, wheelwright, or playwright. Write is a verb that means to form characters (letters, words, pictures) on a surface (paper, screen, wall) with an instrument (pen, keyboard, fingers).
transitive verb. 1a : to form (characters, symbols, etc.) on a surface with an instrument (such as a pen) b : to form (words) by inscribing characters or symbols on a surface write one's name. c : to spell in writing words written alike but pronounced differently.
/ (raɪt) / verb writes, writing, wrote or written. to draw or mark (symbols, words, etc) on a surface, usually paper, with a pen, pencil, or other instrument. to describe or record (ideas, experiences, etc) in writing. to compose (a letter) to or correspond regularly with (a person, organization, etc)
Write is the modern day spelling of the Old English writan, meaning “to score, outline, draw the figure of.” Now it has the sense of “to set down in writing.” You can write music, a short story, or computer code. You can write a letter, or write in cursive.
Well, roughly 5½ years later, it turned out, it wasn't the future... No JVMs on iOS.
But you can definitely do it, i.e., call Swift APIs from Java. That said, it's quite cumbersome, because AFAIK, you have to take a detour via C/C++.
Here's the deal:
The following relies heavily on this question.
Your Java code is in helloworld/SwiftHelloWorld.java
:
package helloworld;
public class SwiftHelloWorld {
static {
System.loadLibrary("SwiftHelloWorld");
}
public static native void printHelloWorldImpl();
public static void main(final String[] args) {
printHelloWorldImpl();
}
}
Now write the native C code (file helloworld_SwiftHelloWorld.c
):
#include <jni.h>
#include <stdio.h>
#include "helloworld_SwiftHelloWorld.h"
#include "helloworld_SwiftHelloWorld_swift.h"
JNIEXPORT void JNICALL Java_helloworld_SwiftHelloWorld_printHelloWorldImpl
(JNIEnv *env, jclass clazz) {
int result = swiftHelloWorld(42);
printf("%s%i%s", "Hello World from JNI! ", result, "\n");
}
Which uses a header file named helloworld_SwiftHelloWorld_swift.h
for our (yet to be written) Swift code:
int swiftHelloWorld(int);
Finally, our Swift code resides in SwiftCode.swift
:
import Foundation
// force the function to have a name callable by the c code
@_silgen_name("swiftHelloWorld")
public func swiftHelloWorld(number: Int) -> Int {
print("Hello world from Swift: \(number)")
return 69
}
To build all this, we first have to compile the Swift code to a dynamic library:
swiftc SwiftCode.swift -emit-library -o libSwiftCode.dylib -Xlinker -install_name -Xlinker libSwiftCode.dylib
We use the -Xlinker
directives to ensure that the dylib's location is relative.
Before we can create the C dylib, we first have to generate the Java headers:
javac -h . helloworld/SwiftHelloWorld.java
Now that we have the Java headers and the Swift dylib, we can compile the C dylib, which links against the Swift dylib:
gcc -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin/" -o libSwiftHelloWorld.dylib -dynamiclib helloworld_SwiftHelloWorld.c libSwiftCode.dylib
Now that everything is in place, we must make sure that both dylibs are in the same directory and that that directory can be found by Java, i.e., you may need to set -Djava.library.path=<dir of your dylibs>
.
Et voilà!
Swift called from Java!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With