Flutter Web位置权限在Mac及iOS端Safari浏览器无法生效问题咨询
你的实现存在以下几个Safari兼容性敏感问题,其他浏览器的容错机制掩盖了这些错误,导致仅Safari端失效:
- API拼写错误
你代码中将标准JS地理定位APIgetCurrentPosition误拼写为getCurrentPostion(少了字母i),Safari对未知API调用没有容错机制,直接会触发调用失败,这是最核心的错误。 - 回调函数格式错误
你调用API时传递的回调参数存在多余嵌套:
// 错误写法:两层函数嵌套,内层allowInterop包裹的函数从未被执行 getCurrentPostion((pos) => allowInterop((GeolocationPostion pos) { _latitude = pos.coords.latitude; _longitude = pos.coords.longitude; }));
外层匿名函数接收参数后仅定义了新函数未执行,_latitude和_longitude永远不会被赋值,正确写法为直接传入被allowInterop包裹的回调函数。
- 异步逻辑错误
getCurrentPosition是异步API,你调用后直接同步返回LocationData,此时回调还未触发,变量均为null值。Safari的异步任务调度优先级低于其他浏览器,不会出现其他浏览器碰巧回调先执行完成的巧合,必然返回空值。 - 缺少Safari权限适配
Safari要求位置权限申请必须由用户主动交互(如点击、触摸事件)触发,禁止页面加载后自动调用定位API,同时要求页面必须运行在HTTPS或localhost环境下,不符合要求时会直接拒绝授权,不会弹出申请弹窗。 - 缺少错误回调处理
标准getCurrentPosition支持传入第二个参数作为错误回调,你未添加错误处理逻辑,出现权限拒绝、定位超时等问题时无法捕获异常,难以定位问题。
修正后参考代码
@JS('navigator.geolocation') library jslocation; import 'package:js/js.dart'; import 'dart:async'; // 修正API拼写 @JS('getCurrentPosition') external void getCurrentPosition(Function success, Function error); @JS() @anonymous class GeolocationPosition { // 修正类名拼写和API保持一致 external factory GeolocationPosition({GeolocationCoordinates coords}); external GeolocationCoordinates get coords; } @JS() @anonymous class GeolocationCoordinates { external factory GeolocationCoordinates({ double latitude, double longitude, }); external double get latitude; external double get longitude; } // 改成异步方法等待回调执行完成 Future<LocationData> getLocation() async { final completer = Completer<LocationData>(); getCurrentPosition( allowInterop((GeolocationPosition pos) { completer.complete(LocationData.fromMap({ 'latitude': pos.coords.latitude, 'longitude': pos.coords.longitude, })); }), allowInterop((err) { completer.completeError(err); }) ); return completer.future; }
使用时需在用户点击事件中调用该异步方法,等待返回结果后再做后续处理。
内容的提问来源于stack exchange,提问作者Mudassir
相关产品推荐
相关产品推荐

