An easy way to get more ratings and reviews for your app!

April 02, 2017

Many of the best indie iOS apps have a prompt in settings asking you to leave a rating on the App Store. Maybe it also includes the number of people who’ve rated the current version, as extra motivation for the first few people to download an update. Good ratings are critical to your marketing plan, and this stuff does work. It’s also extremely unobtrusive compared to some of the other methods of asking for ratings. There’s really not much downside!

Settings

Let’s start with fetching the number of ratings. It sounds tricky, but there’s a simple JSON API for getting this information: http://itunes.apple.com/lookup?id=1115825373 (replace the last parameter with your own app ID). Here’s an example Swift class to fetch the ratings count.

class AppStoreInfoDownloader {
    
    private(set) var ratingCount: Int?
    
    init() {
        fetchAppStoreInfo()
    }
    
    func fetchAppStoreInfo() {
        let appId = Configuration.App.AppStoreAppId
        let url = URL(string: "http://itunes.apple.com/lookup?id=\(appId)")!
        let configuration = URLSessionConfiguration.default
        let session = URLSession(configuration: configuration)
        
        let task = session.dataTask(with: url) { [weak self] (data, response, error) in
            guard let data = data, error == nil else { return }
            do {
                let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any?]
                let results = json?["results"] as? [[String: Any?]]
                let result = results?.first
                self?.ratingCount = result?["userRatingCountForCurrentVersion"] as? Int
            } catch {
                print("Error parsing JSON for iTunes ratings count: \(error)")
            }
        }
        
        task.resume()
    }
}

I’ve simplified this a bit to avoid unnecessary detail. In a real-world app I’d use an NSOperationQueue to manage all of my network operations. Also, keep in mind that the App Store doesn’t report the number of ratings until at least five people have left a review. If you just launched a new app, the userRatingCountForCurrentVersion key may not exist.

In my app I initialize an instance of AppStoreInfoDownloader at launch, so the ratings count is available immediately when the user opens the settings view. Assuming you have a label in your UI to show the ratings count, here’s how you might configure it in viewDidLoad().

fileprivate func updateReviewCount() {
    let version = "version \(Configuration.App.Version)"
    switch appStoreInfo?.ratingCount {
    case .some(let count) where count == 0:
        ratingsCountLabel?.text = "No one has rated \(version) yet. 😞"
    case .some(let count) where count < 10:
        ratingsCountLabel?.text = "Only \(count) \(count == 1 ? "person has" : "people have") rated \(version). 😔"
    case .some(let count):
        ratingsCountLabel?.text = "\(count) people have rated \(version). 🙂"
    default:
        ratingsCountLabel?.isHidden = true
    }
}

If ratingCount is nil I just hide the label. It’s important to check for this case. The user may not have network connectivity, Apple might change the JSON response in the future, or any number of other things could potentially go wrong.

The last part is to handle the user tapping your prompt.

    @IBAction func rateApp(_ sender: AnyObject?) {
        let url = URL(string: "itms-apps://itunes.apple.com/app/id1115825373?action=write-review")!
        UIApplication.shared.open(url, options: [:], completionHandler: nil)
    }

Pay attention to the last parameter, action=write-review! That’s something new that was announced along with the changes to iOS 10.3. It does work with previous versions of iOS (at least the ones I’ve tested), and takes the user directly to the App Store review page without any friction.

If you want to see this in action, you can download my app for guitarists here. And I certainly wouldn’t mind if you left a nice review. 😉

Marc Charbonneau is a mobile software engineer in Portland, OR. Want to reply to this article? Get in touch on Twitter @mbcharbonneau.