I've been googling on how to gracefully handle when user refuse to enable push notification service and location service that my app requires. I found out that Apple's human interface guideline prohibits developers from exiting app programatically and it should be left with users. But I don't want user to use my app without those services enabled since they are neccessary. How do accomplish that without violating any guidelines Apple laid out?
Well, I would just display a static view that explains why those services are required and how the user can enable them - best by offering a button that will redirect to the settings (Swift 3 code):
// in Button handler code:
if let appSettings = URL(string: UIApplicationOpenSettingsURLString) {
UIApplication.shared.openURL(appSettings)
}
A lot of apps implement a "pre-request" dialog, if the user accepts the request on the pre-request then display the actual permission request dialog as they're more likely to accept. If they decline your pre-request dialog, tell them again why you need the permissions or certain features won't function and try again. I haven't heard of Apple having any issues with this approach.
If they've already declined the permission request then you will need to alert them the required permissions haven't been granted and which features are now disabled, offer a dialog button to direct them to settings and display how to enable the permissions.
To open settings from your app use the below code
Swift 3
UIApplication.shared.openURL(URL(string:UIApplicationOpenSettingsURLString)!)
Swift 2.x
UIApplication.sharedApplication().openURL(NSURL(string:UIApplicationOpenSettingsURLString)!)
Objective-C
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]
Update
Just realised you want to limit functionality of your app should user not have required services enabled. The best way is simply to push a view controller that displays an image and/or label stating that certain features aren't enabled and therefore the app can't function. You could detail the steps to enable required services with a button directing them to settings as per above. Again, I haven't seen Apple take issue with this as many apps implement this method should they lack for example GPS.
Related
I would like to customize the following part of the notification permission prompt:
Notifications may include alerts, sounds, and icon badges. These can be configured in Settings.
Is it possible to change this to my own text?
You are not able to customize this message. Read Here for more information.
The recommended way that most apps handle this is by first presenting their own dialog, then show the Apple system dialog.
So when it comes time to ask the user for notification permissions, first you trigger your own custom alert that says something like "Please allow your-app-name to send you notifications..." and maybe a brief description of why the user should allow this. With this alert, only add one action to the UIAlertController, I usually just have the action title set to "Ok" and use .default as the style. In the completion handler of this "Ok" UIAlertAction that is when you will trigger the Apple system dialogue which presents the generic UIAlertController with the option for the user to either accept or deny permissions for your app to send notifications.
So the flow is something like -> users reaches point in app where they have to decide if they want to accept or deny notifications permissions -> app presents UIAlertController that is essentially just an explanation of why the app wants/needs to send notifications -> once user taps "Ok" then trigger the generic system alert that actually makes the user choose to accept or deny notification permission.
There seems to be some psychological advantage to doing it this way. By sort of forcing the user to tap "ok" to notifications in the first dialogue, it primes them to tap "allow notifications" in the generic Apple dialogue displayed immediately after.
EDIT Dec 2020 -
Alternatively what I see a lot of apps doing now is offering an "Accept" action and a "Maybe later" action in their custom alert. If the user taps accept, then the app displays the Apple system alert which allows the user to actually Accept/Deny notifications. If the user taps "Maybe later" then the app does NOT display Apple's system dialogue. This way the user never taps DENY on the Apple system dialogue and therefore the app is still allowed to show it in the future without having to make the user manually change the app's notification preferences via the iOS settings app.
EDIT Mar 2021 - (see #blackjacx comment) Apple has rejected (at least 1) app(s) for using a "priming" dialogue before showing the system alert. So that approach seems like it is no longer allowed.
For anyone who is looking for an updated answer: This is now possible using Xcode 13 (not sure exactly what version introduced it but I was able to see it on Xcode 13.4.1 and not Xcode 13.1) by setting your custom text as the NSUserNotificationsUsageDescription key in info plist file. Unfortunately at the time of writing this, it looks like Apple released this feature with no documentation on it but I can confirm it works on devices with iOS 15.4 and above!
In XCode, you can now click your App name on the left to open it's settings, click on Info, then add a new key called "Privacy - User Notifications Usage Description" -> Then you can set the value to whatever you want that message to say.
No, this is system message, you can't change to custom.
No, I'm fairly certain that that part of the message is out of your control.
I do not believe you can change the iOS prompt, but should maybe make your own. See the guidelines that Apple has provided:
https://developer.apple.com/ios/human-interface-guidelines/interaction/requesting-permission/
Not the best resource because it does state that you can change the subtext (this is specifically for location, photos, etc.) but this, and others, have some good practices:
https://blog.clevertap.com/asking-for-ios-push-notification-permissions/
Basically, you should make your own prompt. Be sure to handle the cases where they have either said no, or turned it off in settings and redirect the user to settings, if so.
Displaying Custom Messaging Before the Alert Ideally, people already know why you’re requesting their permission based on context,
but if it’s essential to provide additional details, you can display a
custom message before the alert appears.
Make it clear that opening the system alert is the only action people
can take in your custom-messaging screen. People can interpret a
pre-alert message as a delaying tactic, so it’s critical to let them
quickly dismiss the message and view the system alert. If you display
a custom screen that precedes a privacy-related permission request, it
must offer only one action, which must display the system alert. Use a
word like "Continue" to title the action; don’t use "Allow" or other
terms that might make people think they’re granting their permission
or performing other actions within your custom screen.
Guidelines here :
https://developer.apple.com/design/human-interface-guidelines/ios/app-architecture/accessing-user-data/
Just to add clarity to Uche Nkadi 's answer, add a "Privacy - User Notifications Usage Description" key in your app's Custom iOS Target Properties. This will change the message on the notification permission alert.
I am working on an app that requires location access. I created a view controller asking the user to allow or not with 2 buttons. But when I click the allow button, device is generating it's own popup asking the user for location access. Can I avoid the popup and just add the functionality of allow in popup into my code for the allow button in my app itself?
No you cannot avoid system popup. As per apple
Always request authorization at the point where you actually plan to
use location services to perform a task. Requesting authorization may
display an alert to the user. If it is not clear to the user that your
app is using location services for a useful purpose, the user may deny
your request to use those services.
Also, It is safe to start location services before the authorization status of your app is determined. Although you can start location services, those services do not deliver any data until the authorization status changes to authorizedAlways or authorizedWhenInUse. To be notified when the authorization status changes, implement the locationManager(_:didChangeAuthorization:) method in your location manager delegate.
Sorce
No, Not possible in Apple device yet.
I have designed an app where the app needs to enable the GPS. There is a page for the user which ask use GPS? To this answer there are 2 options YES and NO. Now my concern is when user clicks on YES he should be directed to settings page and that part is done but now after enabling the GPS from this page the user should redirect to the app again but unfortunately there is no way as there is no back button in the setting page.. Please suggest what I can do in this regards?
As far as I know, the only way to open your app (aside from user tap your app or a related notification) is to do some custom url handling. but unfortunately you can't do such a thing. The other thing you can try is to:
Setup a background thread when your app goes to background
check for location service availability
if it changed to your desired value, open a custom url which in turn will open your app (you should register for hat particular url in your info.plist and such)
but There are some things to keep in mind:
Such Behavior will almost surely get your app rejected by Apple.
in iOS 9+ Apple added a new feature that will help you in this particular problem. when an app gets opened from another app (settings.app for you here) it will add a Back to xxxx in place for network indicator to help user get back were he was.
So, IMHO leave the user experience be as it is for all other applications and don't worry about how he would get back to your app.
I'm trying out this code: http://github.com/akpw/AssetLibraryPhotosViewer to access photos on my iPhone.
However when I run the application, I get an alert that says the application is trying to access my photos - and then I can allow this or decline.
Can I disable this when using the AssetLibrary, or does this message always appear?
If I can't turn this off, and I press "Don't Allow", can I still make the app access my photos?
Following on from answer above. This will appear once. If you allow access then it will not show again and you will have access to the photo's. If you disallow it then you will not be allowed to access this and the alert dialog will not appear again.
This permission can be changed at any time by the user in the settings app (Under Location and Privacy, or a variation of that.) This has been around since iOS 6 I believe.
You are never able to programtically state that access has been granted, the system handles the permissions which are shown to the user.
This is a security feature of the OS that cannot be disabled. If a user does not give your app permission to access the photo library your app will not be able to access any photos. Given this ability your app should be able to handle the situation gracefully from a UI/UX perspective.
For more information take a look at this guide from Apple about iOS security guidelines (page 47 takes about accessing personal data) iOS Security
Is it possible to customize the default alert message when the iPhone wants to use users current location. I want to change not only the text but also the default blue screen alert view. Is it possible ?
Thanks.
Not possible. From documentation,
Important: In addition to hardware not being available, the user has
the option of denying an application’s access to location service
data. During its initial uses by an application, the Core Location
framework prompts the user to confirm that using the location service
is acceptable. If the user denies the request, the CLLocationManager
object reports an appropriate error to its delegate during future
requests. You can also check the application’s explicit authorization
status using the authorizationStatus method.
The alert is prompted by Core location framework. We don't have any control over it.
EDIT : To add up, from this Apple developer forum thread (login required)
That alert is shown in a standard fashion for all applications for
privacy reasons. The user's current location is sensitive
information, and we want to be sure that they give their informed
consent to any use of it on the device. The way that we do that is by
providing a clear, consistent mechanism for the user to give their
consent. If applications were allowed to override or disable the
alert, then that consistency would be lost.
and the answerer is an Apple employee..
Years later, Apple did implement some customization options!
Have a look at the documentation
documentation
If you put one of the following key in your info.plist (depending on your usage of the location services), you can specify a custom string, that is displayed in the default alert additionally.
NSLocationUsageDescription (available since iOS6)
NSLocationWhenInUseUsageDescription (since iOS8)
NSLocationAlwaysUsageDescription (since iOS8)