Java implementation of Objective-C protocol bindings throws unrecognized selector sent to instance

Hello,

I am new to Multi-OS engine (and Objective-C) and have run into some problems.

I have created a protocol in Objective-C which I want to implement as a java interface and use as a callback to call java code from the Objective-C code.

I used the plugin to generate java-bindings from my header file. The bindings works fine in the java -> Objective-C direction (I can create Objective-C objects and call functions from java) but it throws a runtime error when i implement the protocol in java, pass it to Objective-C and then call the java function from Objective-C.
Error: ‚Äúunrecognized selector sent to instance‚ÄĚ

Objective-C header file
(The space after each @ are to avoid being interpreted as mentions)

@ protocol DiscoveryManagerDelegate

  • (void)onDiscover: (NSString *) str;
    @ end

@ interface DiscoveryManager : NSObject
@ property(nonatomic, weak) id delegate;

  • (void)startDiscovery: (NSString *) str;
    @ end

Generated Java interface

@ Generated
@ Runtime(ObjCRuntime.class)
@ ObjCProtocolName(‚ÄúDiscoveryManagerDelegate‚ÄĚ)
public interface DiscoveryManagerDelegate {

@ Generated
@ Selector(‚ÄúonDiscover:‚ÄĚ)
void onDiscover(String str);
}

Java interface implementation:

public class JavaDelegate implements DiscoveryManagerDelegate {

@ Override
public void onDiscover(String str) {
    // 
}

}

Java code:

DiscoveryManager manager = DiscoveryManager.alloc().init();
JavaDelegate delegate = new JavaDelegate();
manager.setDelegate(delegate);
manager.startDiscovery("starting discovery");

Using:
Android Studio 2.3.3
Multi-OS engine plugin 1.3.2
Xcode 8.3.1

Any help or guidance appreciated!

When a method will be only called from Objective-C, ProGuard does not see a reference to it, so it throws these methods out during building.

You should add a proguard.append.cfg file to the root of your iOS module with something like this:

-keep interface DiscoveryManagerDelegate { *; };
-keep class JavaDelegate { *; };

If it still does not work, please share the whole project, so we can take a look.

1 Like

Thank you for solving my last days headache!

I noticed the decompiled JavaDelegate-class was missing the method and adding a proguard-file did indeed solve it.

For anyone running into the same problem I added a proguard.append.cfg with the following: (Note that I had to remove the last semicolon or proguard would throw a ParseExeption)

 -keep interface com.example.package.** { *; }
 -keep class com.example.package.** { *; }