Flutter方法通道传递第三方库User对象的解析问题
解决Flutter与原生平台传递自定义User对象的解析问题
我来帮你搞定这个跨平台数据传递后的解析问题!你现在的实现里,原生端把User对象转成了JSON字符串传给Flutter,其实我们可以优化传递方式,同时在Dart里轻松完成解析,下面分步骤给你说明:
一、优化原生端的数据传递(更简洁,避免字符串转译)
你目前的Android和iOS代码都把数据转成了字符串传递,其实MethodChannel支持直接传递Map/字典类型,这样Flutter端可以直接拿到结构化数据,省去字符串解码的步骤:
Android 端修改:
直接把HashMap对象传给result.success(),不用调用toString():
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()) // 直接传递HashMap,不用转成字符串 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 )) } override fun onError(p0: MyChatException?) { Log.e(TAG, p0?.message) result.error("FAILED", "Unable to create login", null) } }) }
iOS 端修改:
直接把字典传给result,不用转成JSON字符串:
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 ?? "" // 处理可选值,避免nil ] // 直接传递字典 result(data) }) { (error) in // Login error result(FlutterError(code: "FAILED", message:"Login failed with exception: " + error.errorDescription, details: nil)) } }
二、Dart端的解析实现
1. 先定义对应的User模型类
在Dart里创建一个和原生字段对应的User类,再写一个从Map转成User的方法:
class User { final bool result; final String? avatar; final int credits; final String? email; final String lastActive; final String? name; final String? role; final int status; final String? statusMessage; User({ required this.result, this.avatar, required this.credits, this.email, required this.lastActive, this.name, this.role, required this.status, this.statusMessage, }); // 从Map构造User对象 factory User.fromMap(Map<String, dynamic> map) { return User( result: map['RESULT'] as bool, avatar: map['AVATAR'] as String?, credits: map['CREDITS'] as int, email: map['EMAIL'] as String?, lastActive: map['LAST_ACTIVE'] as String, name: map['NAME'] as String?, role: map['ROLE'] as String?, status: map['STATUS'] as int, statusMessage: map['STATUS_MESSAGE'] as String?, ); } }
2. 修改Dart的方法,解析数据
现在可以直接接收Map,然后转成User对象:
import 'dart:convert'; // 如果还是用原来的字符串方式,需要导入这个 Future<User?> loginUser(String UID, String API_KEY) async { try { // 如果用优化后的原生代码,直接接收Map final Map<String, dynamic> result = await platform.invokeMethod('loginUser', {"UID": UID, "API_KEY": API_KEY}); // 转成User对象 return User.fromMap(result); // 如果你暂时不想改原生代码,还是用字符串的话,先解码再转: // final String resultStr = await platform.invokeMethod('loginUser', {"UID": UID, "API_KEY": API_KEY}); // final Map<String, dynamic> result = json.decode(resultStr); // return User.fromMap(result); } on PlatformException catch (e) { print("Login Exception: ${e.message}"); return null; } }
三、进阶:用json_serializable自动生成解析代码(可选)
如果你的模型类字段很多,或者想更规范,可以使用json_serializable包来自动生成解析代码,步骤如下:
- 在
pubspec.yaml里添加依赖:
dependencies: json_annotation: ^4.8.1 dev_dependencies: build_runner: ^2.4.4 json_serializable: ^6.7.0
- 修改User类,添加注解:
import 'package:json_annotation/json_annotation.dart'; part 'user.g.dart'; @JsonSerializable() class User { @JsonKey(name: 'RESULT') final bool result; @JsonKey(name: 'AVATAR') final String? avatar; @JsonKey(name: 'CREDITS') final int credits; @JsonKey(name: 'EMAIL') final String? email; @JsonKey(name: 'LAST_ACTIVE') final String lastActive; @JsonKey(name: 'NAME') final String? name; @JsonKey(name: 'ROLE') final String? role; @JsonKey(name: 'STATUS') final int status; @JsonKey(name: 'STATUS_MESSAGE') final String? statusMessage; User({ required this.result, this.avatar, required this.credits, this.email, required this.lastActive, this.name, this.role, required this.status, this.statusMessage, }); factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); Map<String, dynamic> toJson() => _$UserToJson(json); }
- 运行命令生成代码:
flutter pub run build_runner build
之后就可以用User.fromJson(result)来解析数据了,更省心。
内容的提问来源于stack exchange,提问作者sagar suri
相关产品推荐
相关产品推荐

