A modern utility that reminds your iOS app's users to review the app in a non-invasive way

SiriusRating

A modern utility that reminds your iOS app’s users to review the app in a non-invasive way.

Features

  • SwiftUI and UIKit support
  • Configurable rating conditions
  • Write your own rating conditions to further stimulate positive reviews.
  • Modern design
  • Non-invasive approach
  • Specification pattern used to build the rating conditions
  • Recurring prompts that are configurable using back-off factors
  • No need to reset usage trackers each app version
  • Option to create your own prompt style
  • Unit tested rating conditions
  • Show prompt even while dismissing view controllers

Requirements

  • Xcode 11.1+
  • iOS 13.0+

Setup

Configure a SiriusRating shared instance, typically in your App’s initializer or app delegate’s application(_:didFinishLaunchingWithOptions:) method:

Simple One-line Setup

SiriusRating.setup()

By default the following rating conditions are used:

Default rating conditions
EnoughDaysUsedRatingCondition(totalDaysRequired: 30)
EnoughAppSessionsRatingCondition(totalAppSessionsRequired: 15)
EnoughSignificantEventsRatingCondition(significantEventsRequired: 20)
NotPostponedDueToReminderRatingCondition(totalDaysBeforeReminding: 7)
NotDeclinedToRateAnyVersionRatingCondition(daysAfterDecliningToPromptUserAgain: 30, backOffFactor: 2.0, maxRecurringPromptsAfterDeclining: 2)
NotRatedCurrentVersionRatingCondition()
NotRatedAnyVersionRatingCondition(daysAfterRatingToPromptUserAgain: 240, maxRecurringPromptsAfterRating: UInt.max)

Custom Configuration

SiriusRating.setup(
    requestPromptPresenter: StyleTwoRequestPromptPresenter(),
    debugEnabled: true,
    ratingConditions: [
        EnoughDaysUsedRatingCondition(totalDaysRequired: 14),
        EnoughAppSessionsRatingCondition(totalAppSessionsRequired: 20),
        EnoughSignificantEventsRatingCondition(significantEventsRequired: 30),
        // Important rating conditions, do not forget these:
        NotPostponedDueToReminderRatingCondition(totalDaysBeforeReminding: 14),
        NotDeclinedToRateAnyVersionRatingCondition(daysAfterDecliningToPromptUserAgain: 30, backOffFactor: 2.0, maxRecurringPromptsAfterDeclining: 3),
        NotRatedCurrentVersionRatingCondition(),
        NotRatedAnyVersionRatingCondition(daysAfterRatingToPromptUserAgain: 240, maxRecurringPromptsAfterRating: UInt.max)
    ],
    canPromptUserToRateOnLaunch: true,
    didOptInForReminderHandler: {
        // analytics.track(.didOptInForReminderToRateApp)
    },
    didDeclineToRateHandler: {
        // analytics.track(.didDeclineToRateApp)
    },
    didRateHandler: {
        // analytics.track(.didRateApp)
    }
)

Usage

Significant event

A significant event defines an important event that occurred in your app. In a time tracking app it might be that a user registered a time entry. In a game, it might be completing a level.

SiriusRating.shared.userDidSignificantEvent()

Test request prompt

To see how the request prompt will look like in your app simply use the following code.

// For test purposes only.
SiriusRating.shared.showRequestPrompt()

Rating conditions

The rating conditions are used to validate if the user can be prompted to rate the app. The validation process happens after the user did a significant event (userDidSignificantEvent()). The user will be prompted to rate the app if all rating conditions are satisfied (returning true).

Rating conditions Description
EnoughAppSessionsRatingCondition The rating condition that validates if the app has been launched or brought into the foreground enough times.
EnoughDaysUsedRatingCondition The rating condition that validates if the app has been used long enough.
EnoughSignificantEventsRatingCondition The rating condition that validates whether the user has done enough significant events.
NotDeclinedToRateAnyVersionRatingCondition The rating condition that validates that the user didn’t decline to rate a version of the app. If the user did decline to rate the app, validate if we can show the prompt again by checking the number of days that have passed after the user’s initial decline.
NotPostponedDueToReminderRatingCondition The rating condition that validates if the user didn’t decline the current version of the app. With this condition we do not want to prompt the user to rate the app again if it declined to rate the current version of the app.
NotPostponedDueToReminderRatingCondition The rating condition that validates if the prompt was not postponed due an opted-in reminder. If the user did opt-in for a reminder, it will check if the total number of days have passed to show the prompt again.
NotRatedCurrentVersionRatingCondition The rating condition that checks if the user didn’t already rate the current version of the app. We do not want to prompt the user to rate the app again if it already rated this version of the app.
NotRatedAnyVersionRatingCondition The rating condition that validates that the user didn’t rate any version of the app. If the user did rate the app, validate if we can show the prompt again by checking the number of days that have passed since the user’s rated last.

Custom rating conditions

You can write your own rating conditions in addition to the current rating conditions to further stimulate positive reviews.

class GoodWeatherRatingCondition: RatingCondition {

    private let weatherRepository: WeatherRepository
    
    init(weatherRepository: WeatherRepository) {
        self.weatherRepository = weatherRepository
    }
    
    func isSatisfied(dataStore: DataStore) -> Bool {
        // Only show the rating prompt when it's sunny outside.
        return self.weatherRepository.getWeather().isSunny
    }
    
}

To make use of the new rating condition simply add it to list.

SiriusRating.setup(
    ratingConditions: [
        ...,
        GoodWeatherRatingCondition(weatherRepository: WeatherDataRepository())
    ]
)

Customization

Presenters

StyleOneRequestPromptPresenter (default) StyleTwoRequestPromptPresenter

You can change the presenter to the style you wish.

SiriusRating.setup(
    requestPromptPresenter: StyleTwoRequestPromptPresenter()
)

You can even create your own presenter by extending from RequestPromptPresenter.

class YourCustomStyleRequestPromptPresenter: RequestPromptPresenter {
    
    func show(didAgreeToRateHandler: (() -> Void)?, didOptInForReminderHandler: (() -> Void)?, didDeclineHandler: (() -> Void)?) {
        // Your implementation here. Make sure you call the handlers.
    }
    
}

And implement it as follows.

SiriusRating.setup(
    requestPromptPresenter: YourCustomStyleRequestPromptPresenter()
)

Change texts

You can change the texts by giving the presenter a bundle that contains your custom localized strings.

SiriusRating.setup(
    requestPromptPresenter: StyleOneRequestPromptPresenter(localizationsBundle: Bundle.main)
)

Then you can change the texts in your localizable strings file, for example in: Localizable.strings.

// ...

"request_prompt_title" = "Rate %@";
"request_prompt_duration" = "(duration: less than 10 seconds)";
"request_prompt_description" = "If you enjoy using %@, would you mind taking a moment to rate it? Thanks for your support!";
"request_prompt_rate_button_text" = "Rate %@";
"request_prompt_dont_rate_button_text" = "No, thanks";
"request_prompt_opt_in_for_reminder_button_text" = "Remind me later";

Change tint color

SiriusRating will automatically use the global tint color.

UIView.appearance().tintColor = .red

Or you can set it manually.

SiriusRating.setup(
    requestPromptPresenter: StyleOneRequestPromptPresenter(tintColor: .red)
)

Change app name

SiriusRating will automatically use the app’s display name in the localized texts. If you don’t want to use this name you can set it manually.

SiriusRating.setup(
    requestPromptPresenter: StyleOneRequestPromptPresenter(appName: "App Name")
)

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate SiriusRating into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'SiriusRating'

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate SiriusRating into your Xcode project using Carthage, specify it in your Cartfile:

github "theappcapital/SiriusRating"

Swift Package Manager

The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift compiler.

Once you have your Swift package set up, adding SiriusRating as a dependency is as easy as adding it to the dependencies value of your Package.swift.

dependencies: [
    .package(url: "https://github.com/theappcapital/SiriusRating.git", .upToNextMajor(from: "1.0.0"))
]

Manually

If you prefer not to use any of the aforementioned dependency managers, you can integrate SiriusRating into your project manually.

License

SiriusRating is released under the MIT license. See LICENSE for details.

GitHub

View Github