Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue 251 closing, Open write review page on app store #270

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions Appirater.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ extern NSString *const kAppiraterReminderRequestDate;
#define APPIRATER_CANCEL_BUTTON NSLocalizedStringFromTableInBundle(@"No, Thanks", @"AppiraterLocalizable", [Appirater bundle], nil)

/*!
Text of button that will send user to app review page.
Text of button that will send user to app rate page.
*/
#define APPIRATER_LOCALIZED_RATE_BUTTON NSLocalizedStringFromTableInBundle(@"Rate %@", @"AppiraterLocalizable", [Appirater bundle], nil)
#define APPIRATER_RATE_BUTTON [NSString stringWithFormat:APPIRATER_LOCALIZED_RATE_BUTTON, APPIRATER_APP_NAME]
Expand All @@ -85,12 +85,19 @@ extern NSString *const kAppiraterReminderRequestDate;
*/
#define APPIRATER_RATE_LATER NSLocalizedStringFromTableInBundle(@"Remind me later", @"AppiraterLocalizable", [Appirater bundle], nil)

/*!
Text of button that will send user to app rate & review page.
*/
#define APPIRATER_LOCALIZED_RATE_AND_REVIEW_BUTTON NSLocalizedStringFromTableInBundle(@"Rate and review %@", @"AppiraterLocalizable", [Appirater bundle], nil)
#define APPIRATER_RATE_AND_REVIEW_BUTTON [NSString stringWithFormat:APPIRATER_LOCALIZED_RATE_AND_REVIEW_BUTTON, APPIRATER_APP_NAME]

@interface Appirater : NSObject <UIAlertViewDelegate, SKStoreProductViewControllerDelegate>

/*!
UIAlertController for iOS 8 and later, otherwise UIAlertView
*/
@property(nonatomic, strong) id ratingAlert;
#pragma clang diagnostic pop
@property(nonatomic) BOOL openInAppStore;
#if __has_feature(objc_arc_weak)
@property(nonatomic, weak) NSObject <AppiraterDelegate> *delegate;
Expand Down Expand Up @@ -174,8 +181,12 @@ extern NSString *const kAppiraterReminderRequestDate;
about calling this -- instead, just call the other functions listed above,
and let Appirater handle the bookkeeping of deciding when to ask the user
whether to rate the app.

@param writeReviewPage: is used if StoreKit is unavailable, used to
redirect user to write review in additional to his rating
*/
+ (void)rateApp;

+ (void)rateApp:(BOOL)writeReviewPage;

/*!
Tells Appirater to immediately close any open rating modals (e.g. StoreKit rating VCs).
Expand Down Expand Up @@ -273,6 +284,10 @@ extern NSString *const kAppiraterReminderRequestDate;
*/
+ (void) setDebug:(BOOL)debug;

/*!
'YES' will show button 'Rate and Review' in dialog if StoreKit is unavailable.
*/
+ (void) setShowRateAndReview:(BOOL)rateAndReview;
/*!
Set the delegate if you want to know when Appirater does something
*/
Expand Down
57 changes: 41 additions & 16 deletions Appirater.m
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,14 @@
static UIStatusBarStyle _statusBarStyle;
static BOOL _modalOpen = false;
static BOOL _alwaysUseMainBundle = NO;
static BOOL _rateAndReview = NO;

@interface Appirater ()
@property (nonatomic, copy) NSString *alertTitle;
@property (nonatomic, copy) NSString *alertMessage;
@property (nonatomic, copy) NSString *alertCancelTitle;
@property (nonatomic, copy) NSString *alertRateTitle;
@property (nonatomic, copy) NSString *alertRateAndReviewTitle;
@property (nonatomic, copy) NSString *alertRateLaterTitle;
@property (nonatomic, strong) NSOperationQueue *eventQueue;
- (BOOL)connectedToNetwork;
Expand Down Expand Up @@ -153,6 +155,9 @@ + (void)setModalOpen:(BOOL)open {
+ (void)setAlwaysUseMainBundle:(BOOL)alwaysUseMainBundle {
_alwaysUseMainBundle = alwaysUseMainBundle;
}
+ (void) setShowRateAndReview:(BOOL)rateAndReview {
_rateAndReview = rateAndReview;
}

+ (NSBundle *)bundle
{
Expand Down Expand Up @@ -199,6 +204,11 @@ - (NSString *)alertRateLaterTitle
return _alertRateLaterTitle ? _alertRateLaterTitle : APPIRATER_RATE_LATER;
}

- (NSString *)alertRateAndReviewTitle
{
return _alertRateAndReviewTitle ? _alertRateAndReviewTitle : APPIRATER_RATE_AND_REVIEW_BUTTON;
}

- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Expand Down Expand Up @@ -283,13 +293,20 @@ - (void)showRatingAlert:(BOOL)displayRateLaterButton {
if (NSStringFromClass([SKStoreReviewController class]) != nil) {
#pragma clang diagnostic pop
[Appirater rateApp];
if (@available(iOS 10.3, *)) {
[Appirater rateApp:NO];
} else {
// Otherwise show a custom Alert
NSMutableArray *buttons = [[NSMutableArray alloc] initWithObjects:self.alertRateTitle, nil];

if (_rateAndReview){
[buttons addObject:self.alertRateAndReviewTitle];
}
if (displayRateLaterButton) {
[buttons addObject:self.alertRateLaterTitle];
}
if (NSStringFromClass([UIAlertController class]) != nil) {
if (@available(iOS 8.0, *)) {
[buttons addObject:self.alertCancelTitle];

UIAlertController *alert = [UIAlertController alertControllerWithTitle:self.alertTitle message:self.alertMessage preferredStyle:UIAlertControllerStyleAlert];
Expand All @@ -304,8 +321,10 @@ - (void)showRatingAlert:(BOOL)displayRateLaterButton {
buttonIndex = 1;
} else if ([title isEqual:self.alertRateLaterTitle]) {
buttonIndex = 2;
} else if ([title isEqual:self.alertRateAndReviewTitle]) {
buttonIndex = 3;
}

[self alertViewDidDismissWithButtonIndex:buttonIndex];
}]];
}
Expand Down Expand Up @@ -556,7 +575,7 @@ + (void)appLaunched:(BOOL)canPromptForRating {
}

- (BOOL)isRatingAlertVisible {
if (NSStringFromClass([UIAlertController class]) != nil) {
if (@available(iOS 8.0, *)) {
return ((UIAlertController *)self.ratingAlert).view.superview != nil;
} else {
#pragma clang diagnostic push
Expand All @@ -568,14 +587,9 @@ - (BOOL)isRatingAlertVisible {

- (void)hideRatingAlert {
if ([self isRatingAlertVisible]) {
if (_debug) {
if (_debug)
NSLog(@"APPIRATER Hiding Alert");
}
if ([self.ratingAlert respondsToSelector:@selector(dismissWithClickedButtonIndex:animated:)]) {
[self.ratingAlert dismissWithClickedButtonIndex:-1 animated:NO];
} else {
[self.ratingAlert dismissViewControllerAnimated:NO completion:nil];
}
[self.ratingAlert dismissWithClickedButtonIndex:-1 animated:NO];
}
}

Expand Down Expand Up @@ -666,18 +680,15 @@ + (UIViewController *) topMostViewController: (UIViewController *) controller {
return controller;
}

+ (void)rateApp {
+ (void)rateApp:(BOOL)writeReviewPage {

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion];
[userDefaults synchronize];

// Use the built SKStoreReviewController if available (available from iOS 10.3 upwards)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
if (NSStringFromClass([SKStoreReviewController class]) != nil) {
//Use the built SKStoreReviewController if available (available from iOS 10.3 upwards)
if (@available(iOS 10.3, *)) {
[SKStoreReviewController requestReview];
#pragma clang diagnostic pop
return;
}

Expand Down Expand Up @@ -716,6 +727,11 @@ + (void)rateApp {
reviewURL = [templateReviewURLiOS8 stringByReplacingOccurrencesOfString:@"APP_ID" withString:_appId];
}

if (writeReviewPage)
{
reviewURL = [reviewURL stringByAppendingString:@"&action=write-review"];
}

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:reviewURL]];
#endif
}
Expand Down Expand Up @@ -747,7 +763,7 @@ - (void)alertViewDidDismissWithButtonIndex:(NSInteger)buttonIndex {
case 1:
{
// they want to rate it
[Appirater rateApp];
[Appirater rateApp:NO];
if(delegate&& [delegate respondsToSelector:@selector(appiraterDidOptToRate:)]){
[delegate appiraterDidOptToRate:self];
}
Expand All @@ -761,6 +777,15 @@ - (void)alertViewDidDismissWithButtonIndex:(NSInteger)buttonIndex {
[delegate appiraterDidOptToRemindLater:self];
}
break;
case 3:
{
// they want to rate it
[Appirater rateApp:YES];
if(delegate&& [delegate respondsToSelector:@selector(appiraterDidOptToRate:)]){
[delegate appiraterDidOptToRate:self];
}
break;
}
default:
break;
}
Expand Down
3 changes: 2 additions & 1 deletion en.lproj/AppiraterLocalizable.strings
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!";
"Rate %@" = "Rate %@";
"Rate and review %@" = "Rate and review %@";
"No, Thanks" = "No, thanks";
"Remind me later" = "Remind me later";
"Remind me later" = "Remind me later";
1 change: 1 addition & 0 deletions ru.lproj/AppiraterLocalizable.strings
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Если Вам нравится %@, пожалуйста, поставьте свою оценку. Это займет у Вас не больше одной минуты.\n Спасибо за поддержку!";
"Rate %@" = "Оценить %@";
"Rate and review %@" = "Оценить с отзывом %@";
"No, Thanks" = "Нет, спасибо";
"Remind me later" = "Напомнить позже";
1 change: 1 addition & 0 deletions uk.lproj/AppiraterLocalizable.strings
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!" = "Якщо вам сподобалося %@, будь ласка, поставте свою оцінку. Це займає не більше однієї хвилини.\n Дякуємо за підтримку!";
"Rate %@" = "Оцінити %@";
"Rate and review %@" = "Оцінити з відгуком %@";
"No, Thanks" = "Ні, дякую";
"Remind me later" = "Нагадати пізніше";