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

Wraps #define's in #ifdef's to allow for custom settings (via a pch file) without overwriting the framework's core header file. #41

Open
wants to merge 3 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
63 changes: 62 additions & 1 deletion Appirater.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,50 +44,82 @@ extern NSString *const kAppiraterRatedCurrentVersion;
extern NSString *const kAppiraterDeclinedToRate;
extern NSString *const kAppiraterReminderRequestDate;

/*
NSNotification name for popup click event
*/
extern NSString *const kAppiraterButtonClickedNotification;

/* Sent as the object to the above notification on click */
extern NSString *const kAppiraterNotificationObjectForDeclinedClicked;
extern NSString *const kAppiraterNotificationObjectForRateClicked;
extern NSString *const kAppiraterNotificationObjectForLaterClicked;
extern NSString *const kAppiraterNotificationObjectForOtherClicked;

/*
Place your Apple generated software id here.
*/
#ifndef APPIRATER_APP_ID
#define APPIRATER_APP_ID 301377083

#endif
/*
Your app's name.
*/
#ifndef APPIRATER_APP_NAME
#define APPIRATER_APP_NAME [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]
#endif

/*
This is the message your users will see once they've passed the day+launches
threshold.
*/
#ifndef APPIRATER_LOCALIZED_MESSAGE
#define APPIRATER_LOCALIZED_MESSAGE NSLocalizedString(@"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!", nil)
#endif
#ifndef APPIRATER_MESSAGE
#define APPIRATER_MESSAGE [NSString stringWithFormat:APPIRATER_LOCALIZED_MESSAGE, APPIRATER_APP_NAME]
#endif

/*
This is the title of the message alert that users will see.
*/
#ifndef APPIRATER_LOCALIZED_MESSAGE_TITLE
#define APPIRATER_LOCALIZED_MESSAGE_TITLE NSLocalizedString(@"Rate %@", nil)
#endif
#ifndef APPIRATER_MESSAGE_TITLE
#define APPIRATER_MESSAGE_TITLE [NSString stringWithFormat:APPIRATER_LOCALIZED_MESSAGE_TITLE, APPIRATER_APP_NAME]
#endif

/*
The text of the button that rejects reviewing the app.
*/
#ifndef APPIRATER_CANCEL_BUTTON
#define APPIRATER_CANCEL_BUTTON NSLocalizedString(@"No, Thanks", nil)
#endif

/*
Text of button that will send user to app review page.
*/
#ifndef APPIRATER_LOCALIZED_RATE_BUTTON
#define APPIRATER_LOCALIZED_RATE_BUTTON NSLocalizedString(@"Rate %@", nil)
#endif
#ifndef APPIRATER_RATE_BUTTON
#define APPIRATER_RATE_BUTTON [NSString stringWithFormat:APPIRATER_LOCALIZED_RATE_BUTTON, APPIRATER_APP_NAME]
#endif

/*
Text for button to remind the user to review later.
*/
#ifndef APPIRATER_RATE_LATER
#define APPIRATER_RATE_LATER NSLocalizedString(@"Remind me later", nil)
#endif

/*
Users will need to have the same version of your app installed for this many
days before they will be prompted to rate it.
*/
#ifndef APPIRATER_DAYS_UNTIL_PROMPT
#define APPIRATER_DAYS_UNTIL_PROMPT 30 // double
#endif

/*
An example of a 'use' would be if the user launched the app. Bringing the app
Expand All @@ -99,7 +131,9 @@ extern NSString *const kAppiraterReminderRequestDate;
Users need to 'use' the same version of the app this many times before
before they will be prompted to rate it.
*/
#ifndef APPIRATER_USES_UNTIL_PROMPT
#define APPIRATER_USES_UNTIL_PROMPT 20 // integer
#endif

/*
A significant event can be anything you want to be in your app. In a
Expand All @@ -112,20 +146,47 @@ extern NSString *const kAppiraterReminderRequestDate;
a significant event, call the method:
[Appirater userDidSignificantEvent:];
*/
#ifndef APPIRATER_SIG_EVENTS_UNTIL_PROMPT
#define APPIRATER_SIG_EVENTS_UNTIL_PROMPT -1 // integer
#endif

/*
Once the rating alert is presented to the user, they might select
'Remind me later'. This value specifies how long (in days) Appirater
will wait before reminding them.
*/
#ifndef APPIRATER_TIME_BEFORE_REMINDING
#define APPIRATER_TIME_BEFORE_REMINDING 1 // double
#endif

/*
'YES' will show the Appirater alert everytime. Useful for testing how your message
looks and making sure the link to your app's review page works.
*/
#ifndef APPIRATER_DEBUG
#define APPIRATER_DEBUG NO
#endif

/*
Used simulate usage cases to test popup. Generally, you'll want to set one
or two of them and test the others. -1 == disabled. Leave APPIRATER_DEBUG
set to NO in order to use these.
*/
#ifndef APPIRATER_DEBUG_DAYS_LAPSED_OVERRIDE
#define APPIRATER_DEBUG_DAYS_LAPSED_OVERRIDE -1
#endif
#ifndef APPIRATER_DEBUG_USE_COUNT_OVERRIDE
#define APPIRATER_DEBUG_USE_COUNT_OVERRIDE -1
#endif
#ifndef APPIRATER_DEBUG_SIG_EVENTS_COUNT_OVERRIDE
#define APPIRATER_DEBUG_SIG_EVENTS_COUNT_OVERRIDE -1
#endif
#ifndef APPIRATER_DEBUG_DAYS_LAPSED_SINCE_REMINDER_OVERRIDE
#define APPIRATER_DEBUG_DAYS_LAPSED_SINCE_REMINDER_OVERRIDE -1
#endif




@interface Appirater : NSObject <UIAlertViewDelegate> {

Expand Down
63 changes: 56 additions & 7 deletions Appirater.m
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@

NSString *templateReviewURL = @"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID";

/** Notification message & objects */
NSString *const kAppiraterButtonClickedNotification = @"kAppiraterButtonClickedNotification";
NSString *const kAppiraterNotificationObjectForDeclinedClicked = @"kAppiraterNotificationObjectForDeclinedClicked";
NSString *const kAppiraterNotificationObjectForRateClicked = @"kAppiraterNotificationObjectForRateClicked";
NSString *const kAppiraterNotificationObjectForLaterClicked = @"kAppiraterNotificationObjectForLaterClicked";
NSString *const kAppiraterNotificationObjectForOtherClicked = @"kAppiraterNotificationObjectForOtherClicked";


@interface Appirater ()
- (BOOL)connectedToNetwork;
+ (Appirater*)sharedInstance;
Expand Down Expand Up @@ -124,18 +132,34 @@ - (BOOL)ratingConditionsHaveBeenMet {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

NSDate *dateOfFirstLaunch = [NSDate dateWithTimeIntervalSince1970:[userDefaults doubleForKey:kAppiraterFirstUseDate]];
NSTimeInterval timeSinceFirstLaunch = [[NSDate date] timeIntervalSinceDate:dateOfFirstLaunch];
NSTimeInterval timeUntilRate = 60 * 60 * 24 * APPIRATER_DAYS_UNTIL_PROMPT;
NSTimeInterval timeSinceFirstLaunch;
if (APPIRATER_DEBUG_DAYS_LAPSED_OVERRIDE >= 0) {
timeSinceFirstLaunch = 60 * 60 * 24 * APPIRATER_DEBUG_DAYS_LAPSED_OVERRIDE;
} else {
timeSinceFirstLaunch = [[NSDate date] timeIntervalSinceDate:dateOfFirstLaunch];
}
NSTimeInterval timeUntilRate = 60 * 60 * 24 * APPIRATER_DAYS_UNTIL_PROMPT;

if (timeSinceFirstLaunch < timeUntilRate)
return NO;

// check if the app has been used enough
int useCount = [userDefaults integerForKey:kAppiraterUseCount];
int useCount;
if (APPIRATER_DEBUG_USE_COUNT_OVERRIDE >= 0) {
useCount = APPIRATER_DEBUG_USE_COUNT_OVERRIDE;
} else {
useCount = [userDefaults integerForKey:kAppiraterUseCount];
}
if (useCount <= APPIRATER_USES_UNTIL_PROMPT)
return NO;

// check if the user has done enough significant events
int sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount];
int sigEventCount;
if (APPIRATER_DEBUG_SIG_EVENTS_COUNT_OVERRIDE >= 0) {
sigEventCount = APPIRATER_DEBUG_SIG_EVENTS_COUNT_OVERRIDE;
} else {
sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount];
}
if (sigEventCount <= APPIRATER_SIG_EVENTS_UNTIL_PROMPT)
return NO;

Expand All @@ -149,7 +173,12 @@ - (BOOL)ratingConditionsHaveBeenMet {

// if the user wanted to be reminded later, has enough time passed?
NSDate *reminderRequestDate = [NSDate dateWithTimeIntervalSince1970:[userDefaults doubleForKey:kAppiraterReminderRequestDate]];
NSTimeInterval timeSinceReminderRequest = [[NSDate date] timeIntervalSinceDate:reminderRequestDate];
NSTimeInterval timeSinceReminderRequest;
if (APPIRATER_DEBUG_DAYS_LAPSED_SINCE_REMINDER_OVERRIDE >= 0) {
timeSinceReminderRequest = 60 * 60 * 24 *APPIRATER_DEBUG_DAYS_LAPSED_SINCE_REMINDER_OVERRIDE;
} else {
timeSinceReminderRequest = [[NSDate date] timeIntervalSinceDate:reminderRequestDate];
}
NSTimeInterval timeUntilReminder = 60 * 60 * 24 * APPIRATER_TIME_BEFORE_REMINDING;
if (timeSinceReminderRequest < timeUntilReminder)
return NO;
Expand Down Expand Up @@ -187,8 +216,11 @@ - (void)incrementUseCount {
int useCount = [userDefaults integerForKey:kAppiraterUseCount];
useCount++;
[userDefaults setInteger:useCount forKey:kAppiraterUseCount];
if (APPIRATER_DEBUG)
NSLog(@"APPIRATER Use count: %d", useCount);
if (APPIRATER_DEBUG) {
NSLog(@"APPIRATER Use count: %d", useCount);
} else if (APPIRATER_DEBUG_USE_COUNT_OVERRIDE > -1) {
NSLog(@"APPIRATER Use count (debug override): %d", APPIRATER_DEBUG_USE_COUNT_OVERRIDE);
}
}
else
{
Expand Down Expand Up @@ -335,28 +367,45 @@ + (void)rateApp {
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

NSString *notifObj;

switch (buttonIndex) {
case 0:
{
// they don't want to rate it
[userDefaults setBool:YES forKey:kAppiraterDeclinedToRate];
[userDefaults synchronize];

// Msg for notification
notifObj = kAppiraterNotificationObjectForDeclinedClicked;

break;
}
case 1:
{
// they want to rate it
[Appirater rateApp];

notifObj = kAppiraterNotificationObjectForRateClicked;

break;
}
case 2:
// remind them later
[userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterReminderRequestDate];
[userDefaults synchronize];

notifObj = kAppiraterNotificationObjectForLaterClicked;

break;
default:

notifObj = kAppiraterNotificationObjectForOtherClicked;
break;
}

// Send the notification
[[NSNotificationCenter defaultCenter] postNotificationName:kAppiraterButtonClickedNotification object:notifObj];
}

@end