navigator.permissions.query alternative for iOS Safari - ios

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
}
});

Related

Permission.locationAlways.isGranted always returns false 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

Trouble showing different content on iOS

After 2 days I'm driving myself nuts because I can't resolve this. My issue is as follows:
1.) I am trying to use javascript target an iOS device (regardless of browser being Chrome on apple, Safari, Firefox on apple etc...) to show a different DOM element verses non iOS browsers.
2. ) My iOS detection code is as follows, which I've seen in several other threads: // Detects if device is on iOS
const isIos = () => {
const userAgent = window.navigator.userAgent.toLowerCase();
return /iphone|ipad|ipod/.test( userAgent );
}
3.) After running this check I am attempting the following in both Safari and Chrome on iOS "my way which I'm assuming is incorrect because it's not working lol!" :
if(!isIos()) {
setTimeout(function() {
console.log('showing non iOS banner prompt after delay');
}, 10000);
} else if (isIos()) {
setTimeout(function() {
console.log('showing iOS banner prompt after delay');
}, 10000);
}
4.) The proper log is shown through chrome dev tools on my windows laptop when selecting an iOS device (which I know is not an actual iOS enviroment), but no matter what i do, once loaded to the live site it ALWAYS shows the non Ios log on my iPad.
SOLVED (for iPAD)
After finding this post enter link description here i changed my detection method. I was testing on an iPAD (as this is the only Apple product i own because I'm not a fan) and after this correction my current issue was resolved. I hope this works on other devices as well but won't know until I borrow a freind's. Hope someone else finds this helpful.
||
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)
const isIos = () => {
const userAgent = window.navigator.userAgent.toLowerCase();
return /iphone|ipad|ipod/.test( userAgent ) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
}

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)
}

how to handle iOS notification callback on phonegap cordova?

I don't know if the title say it properly but..
I have a cordova 1.9 app with push notifications using the PushNotification Plugin and UrbanAirship. Everything works fine.
Now I'd like to open a particular page of my app when I lauch/resume my app from a notification.
Is that possible using Javascript ?
I'm totally lost when reading objective-c.
Notifications causes problem to understand JSON structure.
It is not:
if(notifications.length > 0){
But:
if(notifications.notifications.length > 0){
Array is on: notifications.notifications[] structure.
I am not sure how you are trying to load the page but the simplest way would be to call for the pending notifications as it is in javascript and then use window.location.href to load the require page.
I am using this procedure to perform certain task when I have pending notification at application start:
function registerAirship() {
console.log("ready to register for airship");
window.plugins.pushNotification.registerDevice({alert:true, badge:true, sound:true},function(status) {
if (status.deviceToken) {
window.token = status.deviceToken;
if (status) {
registerUAPush(token, "https://go.urbanairship.com/", key, key1, function(){
window.plugins.pushNotification.getPendingNotifications(function(notifications) {
if(notifications.length > 0){
var note = notifications[0];
if(note.applicationLaunchNotification == "1"){
// use the note.aps and redirect to required page
}
}
});
});
} else {
alert("Registration Error: " + status);
}
}
});
}
I was in your position a few days ago. I decided it was easiest to hack objective-c.
So.
1) I found the function that handled my push notification (AppDelegate.m) and called a js function after objective-c had launched execution for handling the notification. After that line, I did this:
[viewController.webView stringByEvaluatingJavaScriptFromString:#"opensometab()"];
2) In the root of my web app application I added this to the pushnotification.js file (you should be able to put it anywhere but I wanted it here).
** My JS function was to activate a tab within the Viewport so yours may be different.
function opensometab(){
var tabPanel = Ext.Viewport.down('tabpanelname');
tabPanel.setActiveItem(3); //index number 3
}

Resources