I have class in Flutter:
class Foo {
String id;
int power;
Foo (this.id, this.power);
Map toJson() => {
'id': id,
'power': power
};
}
I've created a instance of this object and pass it to Android via MethodChannel as a String
:
_myChannel.invokeMethod('custom_event', {
'foo': foo.toJson().toString(),
});
In Android I retrive that string and want to convert to Foo object on Android side so:
val fooString = call.method.argument<String>("foo")
//output: {id: my_id, power: 23}
val response = fooString?.let { Response(it) }
//output {"id":"my_id","power":"23"}
Helper class:
class Response(json: String) : JSONObject(json) {
val data = this.optJSONArray(null)
?.let { 0.until(it.length()).map { i -> it.optJSONObject(i) } } // returns an array of JSONObject
?.map { FooJson(it.toString()) } // transforms each JSONObject of the array into Foo
}
class FooJson(json: String) : JSONObject(json) {
val id: String = this.optString("id")
val power: String = this.optInt("power")
}
How I can convert response to my Kotlin's class?
CodePudding user response:
Since Foo
just contains a string and an integer, both of which are supported by the default message codec, it would make sense to simply pass those two values in a map. (In fact, you already have a method that creates that map, toJson
, though a better name might be toMap
.)
Don't then call toString
on that map; instead use:
_myChannel.invokeMethod('custom_event', foo.toMap());
You are now invoking the method and passing the map. At the native end, you are going to look for the members using their map keys (i.e. id
and power
) using .argument<T>
as you've tried, as follows:
val id = call.method.argument<String>("id");
You could, of course, then create a POJO that wraps an object around those two values, if really necessary.
For more complex messages, consider Pigeon. If you really want to use JSON as your method of serialization, look at the existing JSON message codec.