[iOS] Asking for location services does not present alert request to user

When using asking for location services(unity 5.4.2p2) does not actually happen on ios device (works on unity 5.3.6). The user is never presented with the location service permission alert

To reproduce.

  1. new project

  2. create a script called Gps

     using UnityEngine;
     using System.Collections;
     
     public class Gps : MonoBehaviour {
     
     // Use this for initialization
     IEnumerator Start () {
    
         // First, check if user has location service enabled
         if (!Input.location.isEnabledByUser)
         {
             Debug.Log ("should ask for location");
             // remind user to enable GPS
             // As far as I know, there is no way to forward user to GPS setting menu in Unity
         }
    
         // Start service before querying location
         Input.location.Start();
         Debug.Log ("should start");
    
    
         // Wait until service initializes
         int maxWait = 20;
         while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0)
         {
             yield return new WaitForSeconds(1);
             maxWait--;
         }
    
         // Service didn't initialize in 20 seconds
         if (maxWait < 1) {
             print("Timed out");
         }
    
         // Connection has failed
         if (Input.location.status == LocationServiceStatus.Failed) {
             print("Unable to determine device location");
         }
    
         // Access granted and location value could be retrieved
         else
             print("Location: " + Input.location.lastData.latitude + " " + Input.location.lastData.longitude + " " + Input.location.lastData.altitude + " " + Input.location.lastData.horizontalAccuracy + " " + Input.location.lastData.timestamp);
    
         // Stop service if there is no need to query location updates continuously
         Input.location.Stop();
     }
    

    }

  3. attached to camera

  4. build for ios

  5. play and test on device

as you can see if (!Input.location.isEnabledByUser) does nothing.

I have made a bug report case number 850631

thank you for your time

Starting from iOS 10 Apple requires to set the ‘NSLocationWhenInUseUsageDescription’ field in App’s info.plist file when location services are used (same for Camera & Microphone). You can set it in iOS Player Settings ‘Location Usage Description’.

You should get warnings both when building the project in Unity & in Xcode if location services are used, but the description is not set.

I would also like to point out a few things that may be helpful to others who run into this issue:

  1. The location permissions request in IOS does not seem to get invoked until it is called for in the code. It happens at runtime so if you’re code is not trying to access the location right away, it will not pop up the permissions dialog.

  2. If you are relying on the Unity Docs here: Unity - Scripting API: LocationService.Start then you should probably comment out the first yield break; statement as this may prevent your code from requesting the location data.

    // First, check if user has location service enabled
    if (!Input.location.isEnabledByUser)
    yield break; // try Commenting this out and add some curly braces above while you’re at it…

Ok I was trying to invoke the location permission popup in iOS and none of the above answers indicate a way to do so (though you still need to set the Privacy - Location When In Use Usage Description string in plist or in Player Settings in Unity). My problem is that I am using Mapbox and the first time a user opens the app, the permission popup appears while Mapbox is initializing the map, this had the unfortunate side effect of the map not being able to initialize. The same issue occurred on iOS and Android. So I had to get permission before Mapbox started to initialize the location services/map… Easy enough on Android, but awkward on iOS. Anyhow, I just put an extra scene which loads before the Mapbox scene and I run the code below.


Both iOS and Android need to be treated differently. In the Unity docs, Input.location.isEnabledByUser is supposed to return wether the user has already accepted on both Android and iOS, but I find it is not dependable because iOS returns true no matter. So for iOS I just start the location services early if it is the users first time opening the app which prompts the user to allow location services and Mapbox then initializes without issues. For Android, There was a helpful method for requesting permission as shown below.


Hopefully this is of help to others. Cheers


#if UNITY_ANDROID
using UnityEngine.Android;
#endif

public class NewGameSessionController : MonoBehaviour
{
    private void Start()
    {
            
#if UNITY_ANDROID
        if (!Permission.HasUserAuthorizedPermission( Permission.FineLocation ) )
            Permission.RequestUserPermission( Permission.FineLocation );
            
#elif UNITY_IOS
        if( !PlayerPrefs.HasKey( "HasPlayed") )
            Input.location.Start();
#endif 
    }
}