flutter-geolocator
flutter-geolocator copied to clipboard
iOS Location stream will timeout when manually getting current position
🐛 Bug Report
On iOS simulator, setting the device to a mock location stream (such as City Run) will produce events in Geolocator.getPositionStream().
However, if you call Geolocator.getCurrentPosition() while listening to this stream, the current position will return a result but the position stream effectively dies (will time out if one is set or never return updates if timeout is not set).
Reproduction steps
Below is a minimal flutter app to reproduce the issue.
- Set iOS simulator to "City Run" under "Features" -> "Location"
- Hit "Request Permission" and allow while using app
- Hit "Restart Stream" if not already printing location updates
- Hit "Get Position" and wait ~5 seconds for the stream to error
You can hit "restart stream" and reproduce the error again (stream will listen and print updates until "Get Position" is pressed).
The workaround I am using is to just re-create the stream on a TimeoutException occurs but ideally the stream would keep producing results even if a manual request for location check is made.
class StreamExample extends StatefulWidget {
const StreamExample({Key? key}) : super(key: key);
@override
State<StreamExample> createState() => _StreamExampleState();
}
class _StreamExampleState extends State<StreamExample> {
@override
void initState() {
_setupStream();
super.initState();
}
_setupStream() {
Geolocator.getPositionStream(
locationSettings:
const LocationSettings(timeLimit: Duration(seconds: 5)))
.listen((event) {
print(event);
}).onError((e) {
if (e is TimeoutException) {
print('Stream timeout');
} else {
print(e);
}
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: SafeArea(
child: Column(children: [
TextButton(
onPressed: () {
Geolocator.requestPermission();
},
child: Text('Request Permissions')),
TextButton(
onPressed: () async {
print('Getting position...');
final position = await Geolocator.getCurrentPosition();
print('Manual position was: ${position.toString()}');
},
child: Text('Get Position')),
TextButton(
onPressed: () {
_setupStream();
},
child: Text('Restart stream'))
]),
),
),
);
}
}
Configuration
Version: 8.2.0
Platform:
- [x] :iphone: iOS
- [ ] :robot: Android
I can confirm this. I believe that this problem has existed before and has already been fixed.
Additionally, when you are listening to the location stream but there is no movement of the device i.e. the location stream is not emitting location updates, a manual getCurrentPosition will never return a value.
That's a major break for me.
EDIT: Last working version was 8.0.1
any update on it? Currently, I have to avoid to use getCurrentPosition on iOS.
This might be a duplicate of #1040
Anyone familiar with iOS that can maybe help with a PR to resolve this?
any updates on this? I am running into this as well. The location stream works as expected on initial state. Then the user navigates and calls getCurrentPosition and then returns to the map and the location stream is broken and can't recreate.
The code works fine on android.
@anovis I think it probably won't be getting fixed as it's an issue with the SDK provided by Apple per this comment.
Closing this issue, as it appears to be an iOS problem (see https://github.com/Baseflow/flutter-geolocator/issues/999#issuecomment-1275298975)