vikas27
vikas27

Reputation: 573

Calling Objective-C method from Java

Can anyone please tell me how to call Objectice-C method from Java.

I heard about two techniques for that JNI and JNA.

There is a code written in Objective-C for IOS application and I want to use the code in Java project.

Upvotes: 4

Views: 1868

Answers (3)

JojOatXGME
JojOatXGME

Reputation: 3296

JNA (Java Native Access)

JNA is a library which can be used to access native methods. This is very practical if the rest of your application is written in Java because you can avoid writing any native code.

To interact with Objective-C, you would need to interact with the runtime library of Objective-C. Here is a very basic example.

// This method sets NSWindow.allowsAutomaticWindowTabbing to false.
// Note that it will terminate your application on macOS 10.11 and earlier as described below.
// https://developer.apple.com/documentation/appkit/nswindow/1646657-allowsautomaticwindowtabbing
void disableAutomaticWindowTabbing() {
  Pointer classId = FoundationLibrary.INSTANCE.objc_getClass("NSWindow");
  Pointer selector = FoundationLibrary.INSTANCE.sel_registerName("setAllowsAutomaticWindowTabbing:");
  FoundationLibrary.INSTANCE.objc_msgSend(classId, selector, false);
}

// The interface of the runtime library of Objective-C.
interface FoundationLibrary extends Library {
  FoundationLibrary INSTANCE = Native.load(
      "Foundation",
      FoundationLibrary.class,
      Map.of(Library.OPTION_STRING_ENCODING, StandardCharsets.UTF_8.name()));

  // https://developer.apple.com/documentation/objectivec/1418952-objc_getclass?language=objc
  Pointer objc_getClass(String className);

  // https://developer.apple.com/documentation/objectivec/1418557-sel_registername?language=objc
  Pointer sel_registerName(String selectorName);

  // https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend?language=objc
  // The return type is actually "generic". You might need to declare this function
  // multiple times with different return types if you need them.
  void objc_msgSend(Pointer receiver, Pointer selector, Object... args);
}

Note, however, that JNA cannot handle native exceptions. If objc_msgSend throws an exception, your application crashes immediately. Since setAllowsAutomaticWindowTabbing was not available before macOS 10.12, the example above would throw an exception and crash the application on macOS 10.11 and earlier.

JNI (Java Native Interface)

With JNI, you need to write your own native code (i.e. with Objecttive-C++). For this reason, your project setup becomes more complex. However, it might be a good fit if you expect to write a major part of your logic in Objective-C anyway. Also note that the Objective-C compiler might catch some misusages of the API which can make the application more robust. In contrast to JNA, you are also able to handle native exceptions.

Other

There is also JEP 389: Foreign Linker API (Incubator). I think it is an alternative to JNA but with native support by the JVM. Beside that, there are other libraries and tools which work on top of JNA or JNI to interact with Objective-C specifically.

The blog post Speaking Cocoa From Java from the author of Java-Objective-C-Bridge might also be an interesting read.

Upvotes: 2

technomage
technomage

Reputation: 10059

Rococoa facilitates using ObjectiveC code from Java.

Upvotes: 1

HashtagMarkus
HashtagMarkus

Reputation: 1661

I think this is not possible.

What you can do is write a c/c++-library with the code you want to share and use it in objective-c and java (via JNI). Anyway, you'll have to rewrite your code either to port it to java (where you'd have redundant sourcecode), or to remove your code from your objective-c project and create a c library which you can use in your objective-c and your java project.

Upvotes: 0

Related Questions