1

I have the suggested SharedCode, Android and iOS project structure using the Gradle J2ObjC plugin... where the classes etc in SharedCode are accessed by the main application code of the Android and iOS modules. This works fine.

What I'd like to do is add a fourth module named SharedCodeTestContracts which has a dependency on SharedCode and whose classes etc are to be accessed by the test code of the Android and iOS modules rather than the main application code, as follows:

Module dependencies

The question: Is something like this possible with the J2ObjC Gradle plugin? Can I have two modules that are translated by J2ObjC... one which links to the iOS main application target and the other which contains JUnit tests and links to the iOS test target only?

A bit of context about why: Occasionally I define an interface in the SharedCode module which is to be implemented separately in the Android and iOS modules. To avoid writing the same tests twice (once on each platform) I'd like to have the tests in a shared place which can be accessed by each of the modules.

Adil Hussain
  • 30,049
  • 21
  • 112
  • 147

2 Answers2

1

Here's a starting point.

I'll assume you already have SharedCode/build.gradle working at this point.

In the Android/build.gradle:

dependencies {
    compile project(':SharedCode')
    testCompile project(':SharedCodeTestContracts')
}

Apply the J2objC Gradle plugin to SharedCodeTestContracts/build.gradle, and also make sure you've specified a j2objcLinkage dependency on the shared code:

dependencies {
    compile project(':SharedCode')
    j2objcLinkage project(':SharedCode')
}

Assumption 1: Your Ios module is a pure Xcode ObjC/Swift project (not a Java Gradle project that is compiled with j2objc). If your Ios module is a Java Gradle project, this is still possible, but with a different process. Read https://github.com/j2objc-contrib/j2objc-gradle/blob/master/dependencies.md#dependency-configurations on the various dependency directives you can use. Just like Gradle Java has 'compile' and 'testCompile', J2objc-Gradle has 'test' variants on its dependency directives.

Assumption 2: Arrow from A to B means B depends-on A in your drawing. In addition when you say A links to B you mean that B links in A. I'm clarifying, since both of those are usually the other way around.

When you build all of your Gradle projects, you will get 2 J2ObjC static libraries, one for SharedCode and one for SharedCodeTestContracts. In your iOS Xcode project, have the application target link to just the SharedCode .a file, and have the test target link to both SharedCode and SharedCodeTestContracts.

advayDev1
  • 86
  • 5
  • Thanks for this response @advayDev1. I'll be trying this out this week and I'll let you know if I run into any trouble! – Adil Hussain Feb 23 '16 at 13:37
  • Hey @advayDev1, I tried what you suggested but I'm not seeing the output in my `Podfile` that I would expect. It's too long to write as a comment here so I've added it as an issue here: [Confused by the output to Podfile for a project that has two Java modules](https://github.com/j2objc-contrib/j2objc-gradle/issues/599) Please take a look when you get time and let me know if you can spot something that I'm doing wrong. Many thanks. – Adil Hussain Feb 23 '16 at 17:11
0

Thanks to @advayDev1 for pointing me in the right direction.

The solution is to declare the build.gradle file of the SharedCode module as follows:

plugins {
    id 'java'
    id 'com.github.j2objccontrib.j2objcgradle' version '0.6.0-alpha'
}

dependencies {
    compile 'com.google.guava:guava:18.0'
    testCompile 'junit:junit:4.12'
    testCompile 'org.hamcrest:hamcrest-core:1.3'
}

j2objcConfig {
    autoConfigureDeps true
    minVersionIos '8.4'
    xcodeProjectDir '../iOS'
    xcodeTargetsIos 'MySDK', 'MySDKTests'
    finalConfigure()
}

And to declare the build.gradle file of the TestContracts module as follows:

plugins {
    id 'java'
    id 'com.github.j2objccontrib.j2objcgradle' version '0.6.0-alpha'
}

dependencies {
    compile project(':SharedCode')
    compile 'junit:junit:4.12' // this is compile scope deliberately
    compile 'org.hamcrest:hamcrest-core:1.3' // this is compile scope deliberately
}

j2objcConfig {
    autoConfigureDeps true
    minVersionIos '8.4'
    xcodeProjectDir '../iOS'
    xcodeTargetsIos 'MySDKTests'
    finalConfigure()
}

Based on the above, on building your project you should expect the contents of your Podfile to be the following:

target 'MySDK' do
    platform :ios, '8.4'
    j2objc_SharedCode
    import_other_pods
end

target 'MySDKTests' do
    platform :ios, '8.4'
    j2objc_TestContracts
    j2objc_SharedCode
    import_other_pods
end

There is a bug in the J2ObjC Gradle plugin which doesn't quite produce the expected Podfile output but see here for more on that.

Adil Hussain
  • 30,049
  • 21
  • 112
  • 147