Passing custom object through method channel flutter

7,332

Solution 1

You can pass data in hash map.

In Android:

result.success(hashMapOf(
    "CREDITS" to user.credits,
    "EMAIL" to user.email,
    ...
))

In iOS:

let data: [String: Any] = [...]
result(data)

In Flutter:

final result = await platform.invokeMethod<Map<String, dynamic>>('loginUser', ...);
final credits = result['CREDITS'] as String;
final email = result['EMAIL'] as String;
...

Solution 2

you can use invokeMapMethod which is an implementation of invokeMethod that can return typed maps. like this :

final result = await platform.invokeMapMethod('loginUser', ...);

or you can pass json object as string like that :

in android

platform.success(
    "{\"CREDITS\":\"${user.credits}\",\"EMAIL\":\"${user.email}\",\"LAST_ACTIVE\":\"${user.lastActiveAt}\"}"
)

in flutter

var result = await methodChannel.invokeMethod('loginUser' , '');
var json = json.decode(result);

var credit = json['CREDITS'];
var email = json['EMAIL'];
var lastActive = json['LAST_ACTIVE'];
Share:
7,332
sagar suri
Author by

sagar suri

Updated on December 11, 2022

Comments

  • sagar suri
    sagar suri over 1 year

    I am trying to pass a custom object which is of type User from native platform to Flutter. The User class is part of a library and not accessible directly for editing. Here is my android and iOS code implementation for the same. Problem is I am not able to find a solution on how to pass this object through method channels in such a way that I can parse it in the Dart code easily.

    Android part:

    private fun loginUser(uid: String, apiKey: String, result: MethodChannel.Result) {
            MyChat.login(uid, apiKey, object : MyChat.CallbackListener<User>() {
                override fun onSuccess(user: User) {
                    Log.e(TAG, user.toString())
                    result.success(hashMapOf("RESULT" to true, "AVATAR" to user.avatar,
                            "CREDITS" to user.credits,
                            "EMAIL" to user.email,
                            "LAST_ACTIVE" to user.lastActiveAt,
                            "NAME" to user.name,
                            "ROLE" to user.role,
                            "STATUS" to user.status,
                            "STATUS_MESSAGE" to user.statusMessage).toString())
                }
    
                override fun onError(p0: MyChatException?) {
                    Log.e(TAG, p0?.message)
                    result.error("FAILED", "Unable to create login", null)
                }
            })
        } 
    

    iOS implementation:

    func loginUser(result: @escaping FlutterResult, uid: String, apiKey: String){
            MyChat.login(UID: uid, apiKey: apiKey, onSuccess: { (user) in
                // Login Successful
                let data: [String: Any] = ["RESULT":true,
                                           "AVATAR":user.avatar!,
                                           "CREDITS": user.credits,
                                           "EMAIL": user.email!,
                                           "LAST_ACTIVE":String(user.lastActiveAt),
                                           "NAME":user.name!,
                                           "ROLE":user.role!,
                                           "STATUS":user.status.rawValue,
                                           "STATUS_MESSAGE":user.statusMessage]
                let jsonData =  try? JSONSerialization.data(withJSONObject: data, options: [.prettyPrinted])
                result(String(data: jsonData!, encoding: .ascii))
            }) { (error) in
                // Login error
                result(FlutterError(code: "FAILED", message:"Login failed with exception: " + error.errorDescription, details: nil))
    
            }
        }
    

    My dart code:

        Future<String> isUserLoggedIn() async {
        String status = "";
        try {
          final String result = await platform
              .invokeMethod('loginUser', {"UID": UID, "API_KEY": API_KEY});
          print(result); //How to parse?
        status = "Hello";
        } on PlatformException catch (e) {
          print("Exception");
          status = e.message;
        }
        return status;
      }
    
  • Zufar Muhamadeev
    Zufar Muhamadeev over 4 years
    Does it mean we can't return custom objects?
  • Vinoth Vino
    Vinoth Vino almost 3 years
    I need to send a file object from the flutter app to the iOS native app, I can get the value as dictionary after that which type I need to downcast from any object in swift?
  • Pavel
    Pavel almost 3 years
    @Vinoth consider passing path to file as String
  • Vinoth Vino
    Vinoth Vino almost 3 years
    Yeah thanks, @Pavel. Currently, I'm sending the file path only. But we can also send bytes to native iOS and in the appdelegate, we can get it like let data: FlutterStandardTypedData = call.arguments as! FlutterStandardTypedData