Lyokone / flutterlocation

A Flutter plugin to easily handle realtime location in iOS and Android. Provides settings for optimizing performance or battery.
MIT License
1.08k stars 785 forks source link

getLocation does not complete on iOS devices on the first App start #798

Open Tyniann opened 1 year ago

Tyniann commented 1 year ago

Description Flutter clean has been run. If you run an app that calls getLocation() on any iOS device (tested on different iPhones and iPads) for the first time it never completes. The same code works normally on android devices. I did the necessary checks first if the service is enabled and if the user gave permissions, then call the getLocation function.

Expected behavior The function completes and returns locationdata the first time.

Steps To Reproduce

1.) Start an iOS Simulator and make sure your app isn't already installed. If your app is already installed delete it and restart the device. 2.) Run your app and make sure getLocation() is executed. For example: LocationData locationData; Location location = Location(); locationData = await location.getLocation();

Tested on:

Other plugins:

Additional logs

bensonarafat commented 1 year ago

am also having this issue too

bensonarafat commented 1 year ago

am also having this issue too

alidev0 commented 1 year ago

duplicate of #361

vanlooverenkoen commented 1 year ago

Still not working as it should. This is our current implementation/workaround.

setInitialLocation is used in the splash onLocationChanged is used on the map getLocation is used to "trick this package"

  @override
  Stream<LocationTrackingData> onLocationChanged() {
    if (Platform.isIOS) {
      getLocation();
    }
    return location.onLocationChanged.map((location) => LocationTrackingData(
          latitude: location.latitude,
          longitude: location.longitude,
          accuracy: location.accuracy,
          isMock: location.isMock ?? false,
        ));
  }

  @override
  Future<LocationTrackingData> getLocation() async {
    final location = await this.location.getLocation();
    return LocationTrackingData(
      latitude: location.latitude,
      longitude: location.longitude,
      accuracy: location.accuracy,
      isMock: location.isMock ?? false,
    );
  }

  @override
  Future<void> setInitialLocation() async {
    final status = await this.location.hasPermission();
    if (status != PermissionStatus.granted) return;
    final location = await onLocationChanged().first;
    final lat = location.latitude;
    final lon = location.longitude;
    if (lat == null || lon == null) return;
    _initialLocation = LatLonData(latitude: lat, longitude: lon);
  }
Subrataporwal commented 1 year ago

Any Update on this i am also getting the same issue on IOS

bensonarafat commented 1 year ago

hi @Subrataporwal try geolocation this work fine for me https://pub.dev/packages/geolocator

Subrataporwal commented 1 year ago

hi @Subrataporwal try geolocation this work fine for me https://pub.dev/packages/geolocator

Okay I am gonna try and update it here

loolooii commented 1 year ago

My app is getting rejected by Apple most probably because of this bug. getLocation is not completing/resolving. I have to stop using this plugin, looking at the number of issues, I think it's practically abandoned.

bensonarafat commented 1 year ago

My app is getting rejected by Apple most probably because of this bug. getLocation is not completing/resolving. I have to stop using this plugin, looking at the number of issues, I think it's practically abandoned.

Yeah. Same But I now use https://pub.dev/packages/geolocator

loolooii commented 1 year ago

Using Geolocator as well now and the review got past that point. So thanks for the suggestion @bensonarafat

angeloobeta commented 1 year ago

I'm facing the same issue.

alliejc commented 11 months ago

I'm also experiencing this issue

angeloobeta commented 11 months ago

@alliejc The workaround is to use https://pub.dev/packages/geolocator

lcampanella98 commented 2 months ago

below (dirty) code works for me. (_lastLocationData might be set by an onLocationChanged listener active from elsewhere)

static Future<LocationData> getCurrentLocation() async {
  if (!await _checkOrRequestLocationPermissions()) {
    throw Exception("Location permissions not granted");
  }

  for (int retryCount = 0; retryCount < 2; retryCount++) {
    try {
      if (_lastLocationData != null) {
        return _lastLocationData!;
      }

      final completer = Completer<LocationData>();

      StreamSubscription<LocationData>? locationChangedSubscription;
      try {
        locationChangedSubscription = _location.onLocationChanged.listen((locationData) {
          if (!completer.isCompleted) {
            completer.complete(locationData);
          }
        });

        final locationData = await Future.any([
          _location.getLocation(),
          completer.future,
        ]).timeout(timeoutDuration);

        return locationData;
      } finally {
        locationChangedSubscription?.cancel();
      }
    } catch (e) {}
  }

  throw Exception("Failed to get location within retry limit");
}