Permission.locationAlways.isGranted always returns false ios - ios

I am using the permission_handler package in flutter to access permissions of the underlying device that my app would run on.
My problem, however, is that the Permission.locationAlways.isGranted always returns false, even when I have changed the permission to "always allow" in the app settings.
Here's the function that checks the phone's permission using the permission_handler package:
void _checkLocationPermission() async {
bool isGranted = await Permission.locationAlways.isGranted;
print("isGranted -- $isGranted");
if (_locationPermissionGranted != isGranted) {
setState(() {
_locationPermissionGranted = isGranted;
});
}
}
This function is called in the initState() method of the screen. I would appreciate any guidance to solve this; it seems pretty simple and I don't know what I am doing wrong.

Make sure you installed the package properly on ios. Modify the podfile appropriately as explained here: here. Also, this video may help, in case you're struggling with the instructions in the previous link: video

Related

CrossGeolocator iOS Issue: Either just use events or your own delegate

I've been trying to fix this issue for two days now.
This is a Xamarin.Forms application. The Android side is working perfectly. On the iOS, however, I keept geeting this error.
I have a single button in the center of my screen. When it's clicked, it uses the CrossLocator class to get the Geolocation of the phone. However, this problem keeps ocurring:
Erro: Evento registration is overwriting existing delegate, Either just use events or your own delegate:Plugin.Geolocator.GeolocationSingle-UpdateDelegateCoreLocation.CLLocationManager+_CLLocationManagerDelegate
Here's my code:
`public static async Task<Tuple<Position, string>> GetLocalizacao()
{
var locator = CrossGeolocator.Current;
try
{
locator.DesiredAccuracy = 50;
var position = await locator.GetPositionAsync(TimeSpan.FromMilliseconds(10000));
}
catch (Exception ex)
{
return new Tuple<Position, string>(null, $"Erro: {ex.Message}");
}
var localizacaoFinal = await locator.GetPositionAsync(TimeSpan.FromMilliseconds(10000));
return new Tuple<Position, string>(localizacaoFinal, "");
}`
The exception happens when it hits "GetPositionAsync". From there on, I don't know what to do, nor how to actually identify the issue itself.
If anyone stumbles upon this post, I've been stuck with this issue since I posted it. Still can't get it to work in these conditions. The only way my app worked was downgrading all packages I needed for this.
In order for it to work, it now has:
Xam.Plugin.Geolocator, version 4.5.0.6
Xamarin.Forms, version 5.0.0.2012
Xamarin Essentials, version 1.6.1
Plugin.Permissions, version 6.0.1

Cordova IOS not using NSMotionUsageDescription values

I am updating one of our Cordova apps so everything is up-to-date for IOS and Android.
One of the things I ran into for IOS is the requirement that you have to ask for motion permission.
I was able to get the app to ask for the permission, but unlike the other permissions I am unable to customize the text.
The text is now as follows:
"localhost" Would Like to Access Motion and Orientation
But other permissions show the name of my app in stead of "localhost" and a description which I provided in the config.xml
I did provide a description in the config.xml and even added a description manually in the info.plist file in Xcode, but nothing helps.
I am using Ionic 6.9.2, Cordova 9.0.0 and added the ios#5.1.1 platform to Cordova.
Does anyone now how I can provide a description and fix the "localhost" in the Motion permission request?
maybe this is an old issue, but I hope this answer would be helpful.
you need to comment/remove on some block of code on leaflet.locatecontrol inside node_modules folder.
first go to node_modules -> leaflet.locatecontrol -> src and open file L.Control.Locate.js, then comment/remove following code:
if (this.options.showCompass) {
var oriAbs = 'ondeviceorientationabsolute' in window;
if (oriAbs || ('ondeviceorientation' in window)) {
var _this = this;
var deviceorientation = function () {
L.DomEvent.on(window, oriAbs ? 'deviceorientationabsolute' : 'deviceorientation', _this._onDeviceOrientation, _this);
};
if (DeviceOrientationEvent && typeof DeviceOrientationEvent.requestPermission === 'function') {
DeviceOrientationEvent.requestPermission().then(function (permissionState) {
if (permissionState === 'granted') {
deviceorientation();
}
});
} else {
deviceorientation();
}
}
}

navigator.permissions.query alternative for iOS Safari

I programmed a script that allows visitors of our website to record audio and then saves the file on our server.
Everything worked perfectly until I noticed, that if a user did not give his permission but presses the recording button anyway, the script crashed. Therefore I included this to make sure that permission was granted:
navigator.permissions.query({name:'microphone'}).then(function(result) {
if (result.state == 'granted') {
//GRANTED
} else if (result.state == 'denied') {
//DENIED
}
});
Unfortunately, this does not work for iOS Safari and therefore leads to a crash again in this case. I found several threads about this topic but not a single solution for iOS. But there must be one, right? How should we record audio on an iPhone if we cant make sure that the permission was granted and if recording while under denial of microphone access also leads to a crash?
I hope anyone has an Idea. Thanks in advance.
Daniel
MDN Navigator.permissions (last edit on 2021-09-14) mentions this is an "experimental technology" and the compatibility table shows there's no support for Safari on both MAC and mobile devices (IE and Android WebView as well).
However from an answer from kafinsalim tackling the same issue, the geolocation object is supported on all major browsers. Accessing navigator.geolocation directly without checking permissions raises a permission prompt without throwing errors.
Therefore if you still need to use navigator.permissions check userAgent:
if (!/(safari))/i.test(navigator.userAgent)) {
navigator.permissions.query({ name: 'geolocation' }).then(({state}) => {
switch(state) {
case 'granted':
showMap();
break;
case 'prompt':
showButtonToEnableMap();
break;
default:
console.log('Geo permitions denied');
}});
// https://developer.mozilla.org/en-US/docs/Web/API/Navigator/permissions#examples
} else {
// Safari bypassing permissions
navigator.geolocation.getCurrentPosition(
pos => console.log('success', pos.coords),
e => console.log('failed', e)
);
// https://w3c.github.io/geolocation-api/#handling-errors
}
Please try this one.
navigator.permissions.query({name:'microphone'}).then(function(result) {
if (result.state === 'granted') {
//GRANTED
} else if (result.state === 'denied') {
//DENIED
}
});

Geolocation.requestPermission() only works once

I have an app that needs to request permanent access to geolocation permission ( also in the background ) to gather data.
At the apps start I do a permission check like so ( simplified )
private static function check():void{
if (Geolocation.permissionStatus == PermissionStatus.GRANTED){
onPermGranted();
}else{
_geo = new Geolocation();
_geo.addEventListener(PermissionEvent.PERMISSION_STATUS, onPermission );
try {
_geo.locationAlwaysUsePermission = true;
_geo.requestPermission();
} catch(e:Error){
onError(e);
}
}
};
private static function onPermission(e:PermissionEvent):void{
trace("GeolocationUtil::onPermission: "+e.status);
};
The first time the app starts and this gets called and works.
Now if I quit the app, then change the permission to "never", and restart the app, I can see that
_geo.requestPermission();
gets called, but there is no response whatsoever and I do not get the iOS permissions dialog as well.
Any ideas? Thanks a lot!
The system will only ask once for the permission even if you uninstall your app and reinstall it again, looks like it has a system level cache,
Try go to Setting -> General -> Reset -> Reset Location & Privacy

React native - How to implement iOS Settings

Wondering if someone could help me with this, or at least point me in the right direction.
I've been searching for documentation on how to get/set settings in a React Native iOS app so that those settings appear in the iOS Settings app listed under my app. I see that there is a Settings API, but it appears that the documentation is not complete. The function definitions are listed there, but that's it. No examples or anything.
Can anyone provide me with a simple example, or point me to a tutorial or something that will help me get going? I'm assuming I import Settings from react-native, just like I would do for other APIs, but beyond that I'm not sure where to go.
Thanks.
As stated in React Native documentation :
Settings serves as a wrapper for NSUserDefaults, a persistent
key-value store available only on iOS.
If you want to add iOS Settings bundle to your app you can use this.
As per Chris Sheffield's comment, here is what I have succeeded with so far:
Add a Settings.bundle to your Xcode project
Highlight the project > File > New > File
Choose "Settings Bundle" > Next
I just left the default name: Settings.bundle
Open the Root.plist file inside of the bundle
Make changes based on Apple's documentation (version I'm referencing is archived here: https://web.archive.org/...)
The important value to keep track of is the item's Identifier
Save, compile, and install the app
You can now use Settings.get('<identifier>') like either of these:
const varName = Settings.get('var_name')
const [ varName ] = useState(Settings.get('var_name'));
Notes
I suggest using some method of watching for changes so that your app updates when the user changes settings while it's running, but these are the only parts required.
I do not suggest letting the user also change those specific settings in-app since that goes against the principle of Single Source of Truth, but it's your app, you do what's best for you and your users.
Hope this plugin will help. react-native-permissions
export const _checkPermission = (permissionName) => {
return Permissions.check(permissionName).then(response => {
if (response === 'denied') {
return false
} else if (response === 'authorized') {
return true
} else if (response === 'restricted') {
return false
} else if (response === 'undetermined') {
return false
}
})
}
also, you can use this for asking permission
_requestPermission = (permissionName) => {
return Permissions.request(permissionName).then(response => {
return response
})
}
export const _alertForPermission = (permissionName) => {
return _requestPermission(permissionName)
}

Resources