SKStoreReviewController.requestReview() not working in Live App - ios

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

Related

iOS app not show in Settings app after install

I have an iOS app, which requests location permissions. If the user accepts, everything works fine (of course). But if the user doesn't accept and then manually triggers a localisation, he get the dialog provided by Apple to change the settings for the app in the Settings-App.
But if the user clicks on Settings, it just opens the Settings-App without jumping to the settings of my App. The app is also not listed in the Settings-App mainscreen, but can be found under Privacy -> Location Services.
But once you accept the location (or any other) permissions, the app appears in the Settings and the links work fine.
NSLocationAlwaysAndWhenInUseUsageDescription is included in the pList.
Any ideas on how to guarantee the to appear in the Settings-App mainscreen?
try to check current location permission
and if it's declined show custom alert with this button action
guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return }
if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(settingsUrl)
}

What is the reason to save Firebase authVerificationID?

When logging a user in or signing the user up for the first time and using phone auth it says:
Save the verification ID and restore it when your app loads. By doing
so, you can ensure that you still have a valid verification ID if your
app is terminated before the user completes the sign-in flow (for
example, while switching to the SMS app).
I'm not exactly sure what is the purpose of saving it.
0- the user opens the app and they are on the Login screen
1- the user adds their phone number (below)
2- the callback receives the authVerificationID
3- before the user is taken to the SMS screen, the app is somehow terminated
4- when the user opens the app again, because they haven't logged in yet, they are right back on the Login screen. When they enter their phone number again, they receive either a brand new authVerificationID or the same one (I'm not sure), and they are taken to the SMS screen. Either way both are valid and will get them to the SMS screen.
What does saving the authVerificationID do when no matter what, if the app is terminated, they have to add their phone number again because they will be back on the Login screen?
If the answer is "check if the authVerificationID is saved, and if it is then bring them to the SMS screen instead of the Login screen" then that is bad ux. The user might come back an hour later, when they first open the app they will see the SMS screen and be confused.
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate: nil) { (verificationID, error) in
guard let verificationID = verificationID else { return }
UserDefaults.standard.set(verificationID, forKey: "authVerificationID") // how does this help me?
// A. take user to sms view controller
// B. use authVerificationID && verificationCode for sms sign-in
}
The answer is pretty much what you said - if the user leaves your app in the middle of the auth flow, you can you can resume the sign-in flow from where they left off - i.e. the SMS verification step.
Once the user leaves your app, you have no guarantees that your app will not be terminated. It depends entirely on the OS. So your user might end up in a cycle where they just can't complete the sign-up (however unlikely this case is).
As for bad UX comment - it's very subjective (and depends on your design), and also time-dependent.

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

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

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..

App rejected, Health app permissions

I'm having trouble getting my app approved, and to be honest, I'm having trouble understanding what Apple are on about in this case.
My app only uses HealthKit to create, pause, and finish a workout. It does not read any data.
From Apple:
"Regarding the 2.1 issue, your app displays a window on iOS shortly after launching the watch app to start the process to allow your app to integrate with the Health app. No action takes place after tapping on “Open [AppName].” It would be appropriate to ensure your app displays the Health UI to allow permission to access the Health app."
The problem appears to be with my watchOS app not asking for permission to use the Health app. This is the code I'm using to do so:
In my ExtensionDelegate:
WorkoutManager.sharedManager.requestAuthorisation()
The requestAuthorisation function in my WorkoutManager:
//request workout authorisation only
func requestAuthorisation() {
let writeTypes: Set<HKSampleType> = Set([ HKObjectType.workoutType() ]) //to write a workout
healthStore.requestAuthorization(toShare: writeTypes, read: nil) { (success, error) in
if error != nil {
self.debug.log(tag: "WorkoutManager", content: "Error requesting HealthStore authorisation: \(error!.localizedDescription)")
}
}
}
Also, my iOS app does not use HealthKit (at least at the moment), so I'm not doing anything with HealthKit in the iOS app. Only the watchOS app uses HealthKit.
When you first run the app on the watch, it prompts you to allow authorisation to access the Health app. An accept or deny pop up appears on the iPhone, where you can choose. I thought this is what they were wanting? Surely they don't want me to custom write some "do you want to allow access to the Health app" view controller?
Apple are very strict about their apps, so you will need to have as many details as you can , when the pop up opens it needs to ask the user explicitly if they want to allow it to communicate with the health app

Resources