Flutter iOS认证功能报错:_Map<String,dynamic>无法转为String
Flutter iOS认证功能sendOtp报错问题
问题概述
在Flutter开发的iOS应用中实现认证功能,登录页验证凭据后调用sendOtp方法时出现类型转换错误,导致认证完成后主页面无法正常跳转。
相关代码
User类实现
class User { final String fullname; final String username; final String email; final String password; final String token; final String type; final String id; final String pin; final bool isVerified; User({ required this.fullname, required this.username, required this.email, required this.password, required this.token, required this.type, required this.id, required this.pin, required this.isVerified, }); Map<String, dynamic> toMap() { return { 'fullname': fullname, 'username': username, 'email': email, 'password': password, 'token': token, 'type': type, 'id': id, 'pin': pin, 'isVerified': isVerified, }; } factory User.fromMap(Map<String, dynamic> map) { return User( fullname: map['fullname'] ?? '', username: map['username'] ?? '', email: map['email'] ?? '', password: map['password'] ?? '', token: map['token'] ?? '', type: map['type'] ?? '', id: map['_id'] ?? '', pin: map['pin'] ?? '', isVerified: map['isVerified'] ?? false, ); } String toJson() => json.encode(toMap()); factory User.fromJson(String source) => User.fromMap(json.decode(source)); }
sendOtp方法实现
void sendOtp({ required BuildContext context, required String email, required String sendPurpose, required VoidCallback onTapDialogButton, }) async { try { showDialogLoader(context); http.Response res = await http .post(Uri.parse("$uri/api/sendOtp/$sendPurpose"), headers: <String, String>{ "Content-Type": "application/json; charset=UTF-8", }, body: jsonEncode({ "email": email, })) .timeout(const Duration(seconds: 25)); Navigator.of(context, rootNavigator: true).pop('dialog'); print(res.statusCode); statusCodeHandler( context: context, response: res, onSuccess: () { showAlertMessage( context: context, title: "Verify Account", message: "Please Check Mail For OTP Code", onTap: onTapDialogButton, ); }, ); } on TimeoutException catch (e) { showTimeOutError( context: context, popDialogAndLoader: true, ); } on SocketException catch (e) { showNoInternetError( context: context, popDialogAndLoader: true, ); } on Error catch (e) { print('Send Otp Error: $e'); } }
报错信息
Send Otp Error: type '_Map<String, dynamic>' is not a subtype of type 'String'
解决方案
错误原因分析
该错误是由于代码中将Map<String, dynamic>类型的数据错误地当作String类型处理导致的,大概率出现在statusCodeHandler函数中处理HTTP响应体的逻辑里——当接口返回JSON格式的错误信息时,直接将响应体当作String使用,而没有先解析成Map。
具体修复步骤
修正
statusCodeHandler的响应处理逻辑
确保在处理非200状态码的响应时,先解析响应体为Map,再提取错误信息:void statusCodeHandler({ required BuildContext context, required http.Response response, required VoidCallback onSuccess, }) { if (response.statusCode == 200) { onSuccess(); } else { try { // 解析响应体为Map Map<String, dynamic> errorData = jsonDecode(response.body); String errorMessage = errorData['message'] ?? '未知错误'; showAlertMessage( context: context, title: '错误', message: errorMessage, ); } catch (e) { // 解析失败时直接使用原始响应体 showAlertMessage( context: context, title: '错误', message: response.body, ); } } }补充错误捕获场景
在sendOtp的错误捕获中添加对FormatException的处理,覆盖JSON解析失败的场景:} on FormatException catch (e) { print('JSON解析错误: $e'); showAlertMessage( context: context, title: '错误', message: '数据解析失败', ); }检查用户信息解析逻辑
确认登录后解析用户信息时,是否正确调用对应方法:如果是从接口直接获取Map数据,使用User.fromMap;如果是JSON字符串,使用User.fromJson,避免类型不匹配。验证页面跳转逻辑
检查onTapDialogButton回调中的页面跳转代码,确保用户状态已正确保存,跳转条件没有被错误拦截。
内容的提问来源于stack exchange,提问作者Diana
相关产品推荐
相关产品推荐

