j2objc working with swift

554 views
Skip to first unread message

raheel...@gmail.com

unread,
Feb 12, 2017, 1:54:52 PM2/12/17
to j2objc-discuss
Hi,

I a currently making a Firebase-based SWIFT project with Xcode. I have looked around for any swift to java conversions, but I found nothing good or anything that could help me in any way, until I found j2objc. I was just wondering if j2objc worked with swift, and if it works well.

Thanks in advance.

Christopher Brind

unread,
Feb 12, 2017, 2:21:43 PM2/12/17
to j2objc-...@googlegroups.com
Hi,

This is of interest to me as well and I was looking at this myself recently, but never actually wrote any code in the end because it did seem like a lot of work.  

To summarise my findings... there's no "pure Java" API for Firebase (only an Android one) so converting it from Java to ObjC (which is what this project is about) is probably not possible.  I say probably because I don't believe many Android APIs are used outside of the core/base Firebase package but that might be enough to scupper any attempts to convert it.  

The two obvious options (to me) are:

* Consider using the Firebase C++ API which should work fairly seamlessly on both Android and iOS and would require nothing particularly special re j2objc. However, I don't know how j2objc handles Java native methods or NDK integration.

* Consider building an abstraction for your data layer and hide away the implementation detail of using Firebase and write it specifically for your platform.  

* Some combination of the above - an abstraction for your data layer which delegates to the C++ layer on both platforms but has a custom configuration/setup for Android vs iOS.

Finally there's an old (ie Eclipse era, 2-3 years ago) project that seems to have got something going , but I've no idea what state it's in.  https://github.com/thurn/firebase-xplatform

Obviously, if anyone else has had success in this area it would definitely be interesting to hear about it.

Cheers,
Chris





--
You received this message because you are subscribed to the Google Groups "j2objc-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to j2objc-discuss+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Christopher Brind

unread,
Feb 12, 2017, 2:30:09 PM2/12/17
to j2objc-...@googlegroups.com
I actually seem to have missed your main query though, which is about if j2objc works well with Swift.  It's been a while since I tried and I had some success, but at the end of the day j2objc creates Objective C code so as long as you have a bridging header, in theory you should be good to go - however, it would be good to hear from others with proven experience here. :)

On 12 February 2017 at 18:54, <raheel...@gmail.com> wrote:

Keith Stanger

unread,
Feb 13, 2017, 10:51:25 AM2/13/17
to j2objc-...@googlegroups.com
There are a few things to answer here:

J2ObjC generates Objective-C, which can be bridged and used from Swift. Judging from activity on this list we have several existing users that are using J2ObjC with Swift and we try to be responsive to any Swift related issues.

J2ObjC supports JNI native source. Any existing JNI source in your Android project should "just work" by linking it into your J2ObjC iOS project. Some support provided by JNIEnv may be incomplete so file a bug if you run into problems. Here's a little more info about writing native methods: http://j2objc.org/docs/Writing-Native-Methods.html

Building an abstraction layer is always a good idea when working with platform-specific components. It will make your core logic more testable and make it easier to change your mind about whether a cross-platform implementation is working out. I suggest doing this regardless.

I don't have any in-depth knowledge of Firebase so I can't advise on what will work best for a J2ObjC app.

To unsubscribe from this group and stop receiving emails from it, send an email to j2objc-discus...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "j2objc-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to j2objc-discus...@googlegroups.com.

Daniel Dickison

unread,
Feb 13, 2017, 10:59:52 AM2/13/17
to j2objc-discuss
We're building a sizable app using j2objc for shared backend code (data, networking, caching, etc) with a Swift-based Xcode project for the frontend. It's working perfectly well. Here are a handful of techniques we've found helpful:

- It helps to be diligent about adding @Nullable/@NonNull annotations in the shared java code so the Swift code uses fewer implicitly-unwrapped optionals etc.

- We use a Makefile to run the j2objc translation. This is triggered by an Xcode build target in the main project. Instead of running j2objcc via make, we directly add the translated .h and .m files to the main Xcode project so that they are always compiled with the same build settings as the rest of the project. This means, however, that whenever new shared java classes are added, we need to manually add the translated files to the Xcode project. In addition, new files must be added to the bridging header file manually. This is a pain point, albeit a small one.

- We have some "glue code" written in Swift to provide more "swifty" APIs for commonly-used Java classes. E.g. allowing the use of blocks in place of callback classes, converting to and from Java arrays and lists (e.g. IOSObjectArray) to Swift arrays, JavaNetURL to/from URL, Spanned to NSAttributedString, etc. We also have a wrapper class for calling exception-throwing Java code to convert them to the objc/swift style nil-returning, NSError**-setting method, which can by used with Swift "try".

- We have a "Platform" interface in Java that is implemented by separate singleton objects in Android and iOS. This interface provides native methods that can be called from the shared Java code. E.g. providing access to the user preferences db, localization data, and image manipulation (we have an image cache in the shared code that calls out to these native methods for resizing).
To unsubscribe from this group and stop receiving emails from it, send an email to j2objc-discus...@googlegroups.com.

patrick...@gmail.com

unread,
Feb 24, 2017, 5:43:37 AM2/24/17
to j2objc-discuss
Thanks for these tips, Daniel.

I'm using j2objc with Swift too, and I've had a similar experience as yours. The pain of having to manually add the new files to the Xcode project was solved on our side by a little Ruby script run just after the j2objc step, that uses the xcodeproj gem to add all the generated headers and source files to the target.

Similarly, an umbrella header can be easily updated from the list of generated headers. Then, you only have to add a reference to this header in the bridging header. The downside is that you will expose all your Java classes to Swift, which may not be the most optimal thing to do in terms of build time.

I do have one question, though. J2ObjC generates a lot of forward declarations for java types (eg. JavaUtilList), so you manually have to include the right Java headers in the bridging header for Swift to know about these types. Is there a way around this? How do you deal with this issue?

Tom Ball

unread,
Feb 24, 2017, 1:26:02 PM2/24/17
to j2objc-discuss
j2objc distributions include frameworks for its libraries, which include a header for each framework that includes all public headers. These headers follow the iOS convention of "<framework-name>.h", so your app's bridging header just needs to include the header from each framework it uses. For example, add a dependency on the JRE.framework in your app target, then add '#import "JRE.h"' to the app's bridging header (Xcode may do that automatically now).

To build the j2objc frameworks from source, run "make -j4 frameworks", which will invoke the dist target first. They will then be in dist/frameworks/.

Please note that we aren't Swift developers, and framework requirements may have changed. We really appreciate pull requests and feedback on ways they can be made better (other than our rewriting everything in Swift ;-).

Reply all
Reply to author
Forward
0 new messages