How to check if permission is allowed from settings iOS [duplicate] - ios

This question already has answers here:
Why does viewWillAppear not get called when an app comes back from the background?
(7 answers)
Closed 4 years ago.
I am working on project that needs to load the users contacts. For this I need the contacts information. Thus I am using Contacts Framework. It is easy to use and really very fast also. I am new to iOS so I just used the code snippet of getting contacts information.
What I have done: But I have problem, and that is when the user install the application and go the respective ViewController, the ViewController shows Dialog for permission. There user can Deny and Allow the permission. My app works well when user allows the permission but does not work in other way. So I used a function to check if user has given my app the permission or not.
So I read that when user has not granted the permission we can not do anything. Except we can take him to settings where he can allow the permission and get back the app. here is the code I am using to go to the settings app.
if let appSettings = URL(string: UIApplicationOpenSettingsURLString + Bundle.main.bundleIdentifier!) {
if UIApplication.shared.canOpenURL(appSettings) {
UIApplication.shared.open(appSettings)
}
}
Problem:
now my problem is critical, and that is I know I can take user to
settings view, now what if user still do not allow the Permission and
just get back to our App, in this case how to check if user has given
us permission or not??
I am new to iOS and swift so please help me through example. I have searched a lot but did not find anything. In Android there are callback and also onResume could be used, but in iOS I used ViewWillAppear thinking as equivalent of onResume but that did not work.

If you had a refresh button you could do something like the following:
#IBAction func refreshButtonPressed(_ sender: UIButton) {
ContactsService.sharedInstance.CNContactStore.requestAccess(to: .contacts, completion: { granted, error in
if !granted {
//TODO: - Do something (e.g)
self.[method to display an access denied alert to the user]
return
} else {
[insert your code here]
}
}
Also, as another user has stated in a reply to your original question: Why does viewWillAppear not get called when an app comes back from the background? may be of interest to you. You may want to call the contents of the ContactsService.sharedInstance.CNContactStore.requestAccess( .... { } block inside a function and hook that up to a listener for the UIApplication.willEnterForegroundNotification
https://developer.apple.com/documentation/contacts
https://developer.apple.com/documentation/contacts/cncontactstore
https://developer.apple.com/documentation/contacts/cncontactstore/1402873-requestaccess

Related

ios 14 PHPhotoLibrary.requestAuthorization not calling handler

I had a code to request authorization that worked perfectly on iOS <= 13. When iOS 14 launched, PHPhotoLibrary.requestAutorization with Selected Photos stopped triggering the handler
PHPhotoLibrary.requestAuthorization { status in
if status == .authorized {
DispatchQueue.main.async {
Now the completion is not being called when the user selects Selected Photos. It starts working only after app restart, and more than that, it does not show limited library picker when it does work, so I have to call PHPhotoLibrary.shared().presentLimitedLibraryPicker manualy
I tried doing it the new way with
if #available(iOS 14, *) {
PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in
switch status {
case .authorized:
...
case .limited:
but it doesn't get called here either
I've been battling with this issue for days now, what could be the problem here? I have a feeling that something might be obstructing the views being called, but this code is being called with a press of a UIButton on a UIViewController inside a UITabBarViewController, so I have no idea.
The limited library picker is displayed only once per session:
By default, the system automatically prompts the user to update their limited library selection once per app life cycle.
Also, application shouldn't asks access for photos library before will be relaunched, to check current access level you should use authorizationStatus(for:).
If status is equal to notDetermined, your application should asks access.
If status is limited, you can ask access to display the picker automatically to the user. Also, to allow the iOS to show the picker automatically, your application's plist should does not contain PHPhotoLibraryPreventAutomaticLimitedAccessAlert with true value.
If your application asked access before in current life cycle, the iOS, will no display the picker. Also, I think, the iOS contains some bug with the picker, and will not called the handler.
Here, you can find example of an application that uses new API.

SKStoreReviewController.requestReview() not working in Live App

This is my code for Requesting Review :
if #available(iOS 10.3, *) {
SKStoreReviewController.requestReview()
}
else{
print("Review is not available with in the app")
}
In Development Mode it is working properly & I am able to get PopUp like this:
But In Live app downloaded from appstore, App isnot showing this ratings Popup and nothing happens if user taps out on Ratings Button.
From the documentation:
Although you should call this method when it makes sense in the user experience flow of your app, the actual display of a rating/review request view is governed by App Store policy. Because this method may or may not present an alert, it's not appropriate to call it in response to a button tap or other user action.
(Highlight mine)
If you have a Ratings Button like you said in your question, you should not expect it to show the prompt.
The prompt will only show up if:
The user hasn't disabled Review Prompts in Settings.
The prompt has been shown to the user 3 times or less in a year.
If you must request a review upon user interaction, you must direct your users to the App Store page of your app instead, using code like this (taken from Requesting App Store Reviews Sample Code):
#IBAction func requestReviewManually() {
// Note: Replace the XXXXXXXXXX below with the App Store ID for your app
// You can find the App Store ID in your app's product URL
guard let writeReviewURL = URL(string: "https://itunes.apple.com/app/idXXXXXXXXXX?action=write-review")
else { fatalError("Expected a valid URL") }
UIApplication.shared.open(writeReviewURL, options: [:], completionHandler: nil)
}

InAppReview : SKStoreReviewController So Slow

Using SKStoreReviewController for inAppReview takes time until the prompt appears, is there any way to make it show faster ?
Also, submit button is always dimmed, not allowing me to rate, is this because i didn't upload app to appstore yet?
import StoreKit
protocol InAppReviewProtocol {
func requestInAppReview()
}
extension InAppReviewProtocol {
func requestInAppReview() {
if #available(iOS 10.3, *) {
SKStoreReviewController.requestReview()
} else {
// Fallback on earlier versions
if let appStoreLink = URL(string: Constants.shareApp.url) {
UIApplication.shared.openURL(appStoreLink)
}
}
}
}
No, you can not make is faster, the system decides when to show the alert.
Read apple documentation on SKStoreReviewController.requestReview() for more details.
The submit button is disabled as long as you run your app via XCode to prevent you from giving yourself lots of 5-star votings ;)
See below from the apple docs of requestReview method:-
Although you should call this method when it makes sense in the user
experience flow of your app, the actual display of a rating/review
request view is governed by App Store policy. Because this method may or may not present an alert, it's not appropriate to call it in response to a button tap or other user action.
For more details,
go to
this link
So you got the answer for your first question. Your second question is just simple, in development mode you cannot give rating as it makes sense also. You have to publish your app to appStore first and download app from there and can give a review.
Hope it helps you..

Ask permission for location after user rejected it. Swift 3. IOS [duplicate]

This question already has answers here:
How can I prompt the user to turn on location services after user has denied their use
(11 answers)
Closed 6 years ago.
I'm new to ios, but have the following question.
When the app starts, the user should accept the location permission. This works fine. If he doesn't allow, some features don't work.
However, I want it that when the user tries to use these features, he gets an alert that he didn't accept the location permission. This I also did. However I want the alert to have a button which will allow him to accept it now (so he doesn't have to go into settings on his phone to do it) This I couldn't manage to do.
I made a handler for the alert like this, but it doesn't work to accept the permission.
Here is the handler...
func someHandler(alert: UIAlertAction!) {
print("User now wants to let location from new")
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
}
Is this wrong, What else should I put it. Currently, when the handler is called the location services are not turned on.
Thanks
You can't do what you want. Only the user can change the setting by going to the Settings app.
If you could programmatically change the permission, it would be a security nightmare. And there is no API to force iOS to display the permission alert a 2nd time.

How to show alert view when we access contact in iOS application at very first time when we install application on iOS device?

When we install new app on iOS device, it ask for as a Alert view as a "Do you want to access iPhone contacts in your application. But when I am installing the app first time in iOS device, it is not showing any alert view, So How user will know that he can access iPhone contacts in my application.
Any Solution,
Thank You
This will ask by the apple when you try to use address book.
in the future if you wants to show you can use the following code
-(void)requestAddressBookAccess
{
ViewController * __weak weakSelf = self;
ABAddressBookRequestAccessWithCompletion(self.addressBook, ^(bool granted, CFErrorRef error)
{
if (granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
});
}
else{
}
});
}
iOS shows that alert when you try to access the address book for the first time. So to show it, just read something from the address book.
However, it may be a better experience to "pre-ask" using your own alert first, if you want to give the user information about why you need access to contacts.
This approach was recently discussed here.
Note that, during development, if you ask permissions in your app, then delete and reinstall the app, the permissions are remembered and will not be requested again. You have to go to Settings - General - Reset and reset the location and privacy settings.

Resources