theappcapital/siriusrating-ios
A non-invasive and friendly way to remind users to review and rate an iOS app.
Features
- [x] Supports 32 languages
- [x] Unit tested
- [x] Dark mode compatibility
- [x] Supports SwiftUI and UIKit
- [x] Configurable rating conditions
- [x] Write your own rating conditions to further stimulate positive reviews.
- [x] Modern, sleek design
- [x] Non-invasive prompts
- [x] Configurable recurring prompts with back-off factors
- [x] Create custom prompt styles
Requirements
- iOS 13.0+
- Swift 5.4+
Setup
Configure a SiriusRating shared instance, typically in your AppDelegate or your app's initializer. SiriusRating automatically uses your app's icon and display name in the prompt.
Simple One-line Setup
Using default configuration (e.g. in AppDelegate):
SiriusRating.setup()For example:
//...
func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//...
SiriusRating.setup()
return true
}Or with custom thresholds:
SiriusRating.setup { config in
// Prompt thresholds
config.daysUntilPrompt = 14
config.appSessionsUntilPrompt = 10
config.significantEventsUntilPrompt = 5
// Reminder behavior
config.daysBeforeReminding = 7
// Decline behavior
config.daysAfterDecliningToPromptAgain = 30
config.declineBackOffFactor = 2.0
config.maxPromptsAfterDeclining = 2
// Re-prompt after rating
config.daysAfterRatingToPromptAgain = 240
config.maxPromptsAfterRating = 3
// Custom conditions
config.additionalConditions = [
/* ... */
]
config.customCondition = { dataStore in
// Don't prompt on weekends.
let weekday = Calendar.current.component(.weekday, from: Date())
return weekday != 1 && weekday != 7
}
// Handlers
config.didAgreeToRateHandler = { /* ... */ }
config.didOptInForReminderHandler = { /* ... */ }
config.didDeclineToRateHandler = { /* ... */ }
// Misc
config.canPromptUserToRateOnLaunch = true
}By default, the user will be prompted to rate the app when the following conditions are met:
- The app has been
installed for at least 30 days, - The user has
opened the app at least 15 times, and - The user has
completed 20 significant events.
If the user selects 'Remind me later,' they will be prompted again after 7 days. If the user declines the prompt, they will be prompted again after 30 days, with a back-off factor of 2. This means that if the user declines a second time, they will be prompted again in 60 days, a third time in 120 days, and so on.
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()SiriusRating will validate the conditions after each significant event and prompt the user if all conditions are satisfied.
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()Available Configuration Properties
| Property | Default | Description | |---|---|---| | daysUntilPrompt | 30 | The number of days the app must be installed before prompting | | appSessionsUntilPrompt | 15 | The number of app sessions (launches or foreground entries) before prompting | | significantEventsUntilPrompt | 20 | The number of significant events before prompting | | daysBeforeReminding | 7 | The number of days to wait before reminding a user who chose "Remind me later" | | daysAfterDecliningToPromptAgain | 30 | The number of days to wait before prompting again after the user declines | | declineBackOffFactor | 2.0 | The back-off multiplier applied for each successive decline (e.g. 30, 60, 120 days). Set to nil to disable | | maxPromptsAfterDeclining | 2 | The maximum number of times the user can be re-prompted after declining | | daysAfterRatingToPromptAgain | 240 | The number of days to wait before prompting a user who has already rated | | maxPromptsAfterRating | UInt.max | The maximum number of times the user can be re-prompted after rating | | debugEnabled | false | When true, prints diagnostic information to the console. Automatically disabled in non-DEBUG builds | | canPromptUserToRateOnLaunch | false | When true, checks conditions and potentially shows the prompt on app launch or foreground |
Installation
CocoaPods
To integrate SiriusRating into your Xcode project using CocoaPods, specify it in your Podfile:
pod 'SiriusRating'Carthage
To integrate SiriusRating into your Xcode project using Carthage, specify it in your Cartfile:
github "theappcapital/SiriusRating-iOS"Swift Package Manager
dependencies: [
.package(url: "https://github.com/theappcapital/SiriusRating-iOS.git", .upToNextMajor(from: "2.0.0"))
]Styles
| StyleOneRequestPromptPresenter (light, default) | StyleOneRequestPromptPresenter (dark, default) | | --- | --- | | [Style One (light)] | [Style One (dark)] |
| StyleTwoRequestPromptPresenter (light) | StyleTwoRequestPromptPresenter (dark) | | --- | --- | | [Style Two (light)] | [Style Two (dark)] |
Customization
Custom rating conditions
You can write your own rating conditions in addition to the default 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
}
}Add it alongside the default conditions:
SiriusRating.setup { config in
config.additionalConditions = [
GoodWeatherRatingCondition(weatherRepository: WeatherDataRepository())
]
}For simple conditions, you can use an inline closure instead of a class:
SiriusRating.setup { config in
config.customCondition = { dataStore in
// Don't prompt on weekends.
let weekday = Calendar.current.component(.weekday, from: Date())
return weekday != 1 && weekday != 7
}
}Change prompt style
SiriusRating.setup { config in
config.requestPromptPresenter = StyleTwoRequestPromptPresenter()
}Change texts
You can change the texts by giving the presenter a bundle that contains your custom localized strings.
SiriusRating.setup { config in
config.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 = .redOr you can set it manually.
SiriusRating.setup { config in
config.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 { config in
config.requestPromptPresenter = StyleOneRequestPromptPresenter(appName: "App Name")
}License
SiriusRating is released under the MIT license. See LICENSE for details.
Package Metadata
Repository: theappcapital/siriusrating-ios
Default branch: master
README: README.md