Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serializing a Swift class to JSON using J2ObjC and GSON library

I'm very new to iOS, moving from Android development.

We have an Android application which has several libraries which we're using J2ObjC to translate into Objective C.

I've been gradually bringing over the libraries and so far, so good.

However, after translating Google's GSON library I have an issue where if I try and use the translated method toJsonWithId I come across problems:

    let gson = ComGoogleGsonGson()
    let swiftTest = GsonSwiftTest()
    swiftTest.name = "Ricky"
    print(gson.toJsonWithId(swiftTest))

I receive the following error:

libc++abi.dylib: terminating with uncaught exception of type JavaLangAssertionError

Further it shows:

Terminating app due to uncaught exception 'JavaLangAssertionError', reason: 'unknown Java type encoding'

My Swift class is:

import Foundation

@objc
public class GsonSwiftTest : NSObject {

   var name:String?

}

If I instead use an Objective C class in my Swift project, add it to the bridging header and use the Objective C class it works fine.

I believe this is a misunderstanding on my part, but I can't find the answer as to why this won't work. Checking the J2ObjC source code shows the error is raised when the type of class can't be found.

If anyone could help explain the reasons for this issue, it'd be appreciated.

Thanks!

like image 646
Ricky Avatar asked Oct 08 '15 09:10

Ricky


1 Answers

There's a much easier way to serialize Swift instances: use the Foundation class NSJSONSerialization directly. Here's a relevant blog posting: JSON Serialization in Swift.

The reason your test fails in Swift is that not all Swift classes extend NSObject, which j2objc maps to java.lang.Object. All Java serialization frameworks assume/require that all classes extend Object, like they do in Java.

For a cross-platform API, I recommend creating a simple serialize/unserialize interface, then implement it once for Android using GSON, and once natively using NSJSONSerialization. Swift is evolving rapidly, so if a better serialization mechanism becomes available, your project can easily take advantage of it without affecting the Android port.

like image 166
tball Avatar answered Oct 20 '22 05:10

tball