Home Features Docs Blog Support GitHub

MOE Community Edition Gradle Plugin & SDK 1.6.0

WARN: This update might contain breaking changes, please read the following carefully before updating the version!


Changelog

  • iOS binding updated to iOS SDK 13.4
  • SDK runtime build with latest Xcode 11.4 and iOS SDK 13.4.
  • Fix EXC_BAD_ACCESS KERN_INVALID_ADDRESS crash in art::Thread::Attach()
  • Fix Natjgen bindings for method argument types and return type in protocol bindings.
    • This introduces potential breaking changes to your code.

Details

The most significant change of this build is fixing a bug in binding generating.
When dealing with the following Objective-C protocol code:

@protocol Protocol1

@property (nonatomic, strong) id <SomeType> prop_1;

@end

The SDK < 1.6 will produce Java code like this:

@Generated
@Runtime(ObjCRuntime.class)
@ObjCProtocolName("Protocol1")
public interface Protocol1 {
	@Generated
	@Selector("setProp_1:")
	void setProp_1(@Mapped(ObjCObjectMapper.class) Object value);

	@Generated
	@Selector("prop_1")
	@MappedReturn(ObjCObjectMapper.class)
	Object prop_1();
}

As you could notice that the parameter and return type is Object not SomeType that in the Objective-C file. This issue could happen to any method in a protocol that has parameter type or return type that is object id (e.g. id <XXX>).

However if any Objective-C class implements this protocol directly, like:

@interface Class1 : NSObject <Protocol1>

@property (nonatomic, strong) id <SomeType> prop_1;

@end

The generated Java binding will have the correct argument type and return type:

@Generated
@Runtime(ObjCRuntime.class)
@ObjCClassName("Class1")
@ObjCClassBinding
public class Class1 extends NSObject implements Protocol1 {
	@Generated
	@Selector("setProp_1:")
	public native void setProp_1(@Mapped(ObjCObjectMapper.class) SomeType value);

	@Generated
	@Selector("prop_1")
	@MappedReturn(ObjCObjectMapper.class)
	public native SomeType prop_1();
}

Then you will get a Java compiling error since the method signature does not match.

This release fixes this issue, which could break your code since now the argument types in protocol bindings (and its child class bindings) will be a specialized type instead of Object.

You could get a compiling error like “method does not override or implement a method from a supertype” (when overriding method from superclass) or “ClassA is not abstract and does not override abstract method MethodX in InterfaceB” (when implement an interface that generated from Objective-C protocol).

To fix the issue, simply change the method argument type / return type in child class to be the same as its super class.

NB: If you override some method without adding the @Override annotation, you might not get the compiling error and the app might seems to be functional initially. However your code might behave weirdly or crash at random spot since a method you intended to override is actually NOT overridden. Make sure to test your app carefully and NEVER, EVER omit the @Override annotation!


Install / Upgrade

Simply change you build script to use the new plugin and SDK:

buildscript {
    dependencies {
        classpath group: 'org.multi-os-engine.community', name: 'moe-gradle', version: '1.6.0'
    } 
}
7 Likes