While working on my latest update of Fin, I spent a bit of time playing with Apple’s new SKStoreReviewController API.
For those unfamiliar, this new API was announced with the early betas of iOS 10.3, and it went live with the 10.3 release last month. Though it isn’t the only approved way to prompt a customer to rate your app on the App Store yet, that is Apple’s ultimate intention. Like it or not, you’ll have to learn to work with this thing eventually, in other words. Unless you never prompt for reviews.
I wanted to share a thing or two I learned in my research and implementation for Fin. I had never had any ratings prompts in any of my apps before (I don’t count putting a link on the settings or help screen. That’s not prompting, it’s merely offering easy access.) So when this new controller was announced, I figured I might as well use it, rather than roll my own.
If you have a method of prompting for reviews that works for you already, I’d say leave it as is for now. Apple will make you replace it eventually, but especially if yours is better/more effective, feel free to keep yours as long as you can.
What do I mean by better? Well, frankly, I think SKStoreReviewController isn’t the ideal way to prompt customers for a review. It’s an alert dialog, for one thing, which means it needs to be handled immediately before proceeding with the app. I don’t think ratings are so important they should get in the way of my customer using the app. Embedding it into a tableView cell or collectionView, as implemented by an app like Slopes, for instance, would be greatly preferred. Or, as suggested by Oisín Prendiville, a notification would also be less intrusive.
Another issue with SKStoreReviewController: It only prompts for a star rating, not a review. If a customer wishes to review your app, they will still need to go outside to the App Store to do it. (At least we have the new deep link to directly take the customer to the review tab.)
Having said all that, here’s how I approached implementing SKStoreReviewController for Fin, given its limitations. Perhaps some readers will have some suggestions on how I can improve this.
First, the logic. When do I want this thing to pop up? The way I see it, there are only two possible times that make any sense. Fin is a timer app, so you would never want a rating alert to pop up during a running timer. That leaves the time immediately after app launch, before you start a timer, and the moment you acknowledge a timer has ended by tapping to stop the flashing ending animations. I opted for the latter. (I’m not a fan of apps that prompt for reviews on launch. If I’ve launched your app, I want to use it, not be held up by a prompt.)
I don’t want the prompt happening every time someone finishes a timer, of course (and I can’t with SKStoreReviewController, anyway—more on that in a minute) so I store a date in NSUserDefaults when I request a prompt, and don’t request another prompt until at least two months have passed from that date.
Notice I said “I requested” a prompt. Not “I showed” a prompt. Or “I prompted.” As the name of the sole method available on SKStoreReviewController implies (requestReview), you can’t prompt a customer for a review yourself. You can only request that the App Store prompt the customer for a review.
You get no feedback from the system that this request was approved, by the way, so you will have no way of knowing whether the customer was actually prompted. A request is just that; a request. This is why you can never pop up this review prompt from a “Rate” button. The button may end up doing nothing, and you’ll never be notified as the developer.
Apple hasn’t made public the criteria for saying yes to one of these requests, other than to say that the request will not be approved more than three times a year, but I have a few guesses as to when your request might also be denied.
- If the customer has already given a rating for this version.
- If the device is not connected to the internet.
- If a prompt has been given recently by the same app (within some interval Apple determines).
- If another app’s prompt was approved recently (again, within some interval Apple determines). I could see Apple not wanting to bombard a single customer with prompts from several apps in the same day, for instance.
- If a customer with the same AppleID has been given a prompt by this app on another device recently.
It’s actually good in some ways that Apple can make these determinations, as it has far more information than you do about what your customer has been doing outside the little world of your app, and thus can minimize the likelihood of being annoying. Annoyed customers do not leave five-star reviews.
That, of course, assumes you trust Apple to do this well, and it depends on whether you believe, as I do, that prompting for ratings is a necessary evil, not a sport. I want prompts to be done as infrequently and as unobtrusively as possible, while still helping me reach my business goals.
The downside, of course, is the lack of a callback when the request was denied. Not knowing whether my request was approved by the App Store means I now have to make a decision about resetting that two-month clock after making the request.
If I don’t reset the clock, I could theoretically burn out all my prompts for the year on the first three times someone finishes a timer. If I reset the clock in situations where I’m very likely to have been denied, the customer might never see the prompt.
So here’s what I do in my class for determining whether to make a prompt request:
- I check for connection to the internet. If there’s no internet, there will be no prompt. I’ve confirmed this in my own testing. In the Simulator and in debug builds on device, the request is basically always honored, so you can test your own logic and see the prompt for yourself. When you have no internet connection, however, the prompt won’t show up, even in debug mode. Makes sense, given that if there’s no internet connection, you won’t be able to leave a rating, anyway.
- I check to see if you are doing a remote session. Fin 4.0 added the ability to connect two or more devices together to run a single timer in sync. This could be an inconvenient scenario in which to see a prompt, even at the timer’s end, because your remote device may be on a stage during a performance, set to be controlled from an AV station. So I opted to not make a request during these remote sessions.
- I check to see if you are remote-controlling your Fin session via Apple Watch. Again, there’s a chance here that you put your iPhone out of reach when opting to control via Apple Watch, so I don’t want to request a review then, either.
If all the above criteria give me the thumbs up, and it’s been at least two months since the last request date, I request a review when the customer taps at the end of a timer, and I reset the date to today. Maybe the prompt happens; maybe it doesn’t. At that point, it’s out of my hands.
In addition, I sync the last request date via iCloud for those who have turned on iCloud sync. I don’t want someone getting a rating prompt on iPad and iPhone right after one another. (Again, I think Apple may do this already, but just to be sure.)
Why two months? It seemed long enough to me. I could have gone for three or four months, but then there’s a risk the customer won’t be in the correct set of circumstances at least three times a year. If a customer gets all three prompts in the first six months, so be it. I’m not going to lose sleep over it. At least it’ll be spread over six months, minimum.
Some folks have suggested that I tie in the review prompt to the version number as well, but I didn’t do that for a number of reasons. First, Apple will only approve a prompt three times a year, regardless of version number. Second, I believe (and yes this is speculation) that the App Store will know that a user has already rated a current version and thus not approve a prompt again once a person rates for that version, anyway. (At least, that’s how I’d do it.) If I only request a review prompt once per version, then when the customer says “Not Now”, I will lose that customer for the entire version. I know for myself, I often say “Not Now” because now isn’t a convenient time, not because I’m not interested in reviewing tomorrow. Third, Fin is a side project for me, so I don’t anticipate putting out many versions every year. I only released one version in 2016, for instance. I wouldn’t want to only have one opportunity a year to prompt for a rating, especially when I can’t be certain my request was approved that one time.
You’ll have to determine what works best for your app, of course. I welcome suggestions from anyone who has ideas for improving this prompting logic.
And if Apple wants to improve the SKStoreReviewController by making it an embeddable view, or a notification, I’d welcome that. The nice thing is they could do that without breaking anything for us.
Heck, if they wanted to remove ratings altogether, or at least change to a simple thumbs up, thumbs down, I’d be all for that, too. Again, this would require no effort from anyone who is using SKStoreReviewController, either. Which is nice. And it’s probably why Apple wants us all using this thing rather than our home-grown solutions sooner rather than later.