M1设备Flutter应用iOS模拟器加载Google Maps崩溃求助
问题根因
这个崩溃和M1芯片、Google Maps SDK本身没有直接关系,错误栈已经明确给出原因:sendSMS方法执行时调用了值为null的函数,属于Dart层空指针错误。Android、Web端接口返回时序和iOS端存在差异,没有命中空调用的时机,所以表现为仅iOS端加载地图前崩溃。
现存代码问题
togglePinField、toggleMapField两个回调参数没有做必填约束和非空校验,父组件漏传或者组件生命周期变化导致回调为空时,直接调用就会触发你看到的NoSuchMethodError- 发送验证码的加载状态
isProcessing没有完整的赋值逻辑:点击按钮发起请求时没有置为true,请求结束(成功/失败/异常)后也没有重置为false,容易出现重复点击、组件状态和实际业务流程不同步的问题 - 异步请求过程中没有判断组件是否还挂载,请求返回时如果组件已经销毁,后续调用setState或者回调都会触发异常
修复步骤
- 给
PhoneNumberInput组件的回调参数加必填约束,从定义层避免漏传回调:
class PhoneNumberInput extends StatefulWidget { final Future<void> Function() togglePinField; final Future<void> Function() toggleMapField; final Function(String) changePhoneNumber; const PhoneNumberInput({ super.key, required this.togglePinField, required this.toggleMapField, required this.changePhoneNumber, }); @override State<PhoneNumberInput> createState() => _PhoneNumberInputState(); }
- 重构
sendSMS方法,补全状态管理、挂载判断和异常捕获:
sendSMS() async{ // 发起请求前先置加载态,禁止重复点击 setState(() { isProcessing = true; }); try { var data = convert.json.encode({ 'number': "+1$phoneNumber", }); var requestHeaders = { 'Content-type': 'application/json', 'Accept': 'application/json', }; var url = Uri.parse( 'https://us-central1-sonic-strains.cloudfunctions.net/app/api/twilioVerifyandSendCode'); var response = await http.post(url, body: data, headers: requestHeaders); // 组件已销毁直接终止后续逻辑 if (!mounted) return; if (response.statusCode == 200) { print("Calling toggle pin field"); await widget.togglePinField(); print("Calling toggle map field"); await widget.toggleMapField(); } else { print('Request failed with status: ${response.statusCode}.'); print("sendSMS error: $response"); } } catch (e) { print("sendSMS exception: $e"); } finally { // 无论请求成功失败,都重置加载态 if (mounted) { setState(() { isProcessing = false; }); } } }
- 修复完上述空指针问题后,如果M1模拟器上加载Google Maps仍然触发原生崩溃,再做iOS端架构兼容配置:
- 打开iOS工程目录下的
Podfile,在post_install钩子中添加Google Maps对应的arm64模拟器架构支持配置 - 依次执行
flutter clean、删除Podfile.lock文件、执行pod install --repo-update重新安装依赖 - 不需要用Rosetta转译启动Xcode,直接使用原生arm64版本运行即可
- 打开iOS工程目录下的
验证方法
修复后先在iOS模拟器运行,观察日志确认接口返回200时,两个回调方法调用前不再出现空值异常,不会再抛出NoSuchMethodError后,再验证地图加载流程即可。
内容的提问来源于stack exchange,提问作者Sonic Strains
相关产品推荐
相关产品推荐

