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

Adjust interface to allow better use as a Library #33

Open
wants to merge 5 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
11 changes: 11 additions & 0 deletions Appirater.bundle/de.lproj/Appirater.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Appirater.strings
Appirater

Created by Martin Kavalar on 11/15/10.
*/
"AppiraterMessage" = "Gefällt Dir %@? Dann bewerte es doch kurz. Es dauert nur eine Minute. Danke für Deine Unterstützung!";
"AppiraterTitle" = "%@ bewerten";
"AppiraterCancelButton" = "Nein, danke";
"AppiraterRateLaterButton" = "Später nochmal fragen";
"AppiraterRateButton" = "%@ bewerten";
11 changes: 11 additions & 0 deletions Appirater.bundle/en.lproj/Appirater.strings
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
Appirater.strings
Appirater

Created by Martin Kavalar on 11/15/10.
*/
"AppiraterMessage" = "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!";
"AppiraterTitle" = "Rate %@";
"AppiraterCancelButton" = "No, Thanks";
"AppiraterRateLaterButton" = "Remind me later";
"AppiraterRateButton" = "Rate %@";
51 changes: 10 additions & 41 deletions Appirater.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,41 +43,18 @@ extern NSString *const kAppiraterCurrentVersion;
extern NSString *const kAppiraterRatedCurrentVersion;
extern NSString *const kAppiraterDeclinedToRate;

/*
Place your Apple generated software id here.
*/
#define APPIRATER_APP_ID 301377083
#define kAppiraterBundleName @"Appirater.bundle"

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

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

/*
This is the title of the message alert that users will see.
*/
#define APPIRATER_MESSAGE_TITLE [NSString stringWithFormat:@"Rate %@", APPIRATER_APP_NAME]
/*
Your app's name.
*/
#define APPIRATER_APP_NAME [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]

/*
The text of the button that rejects reviewing the app.
*/
#define APPIRATER_CANCEL_BUTTON @"No, Thanks"
#define AppiraterLocalize(StringToken) NSLocalizedStringFromTableInBundle(StringToken, @"Appirater", appiraterBundle(), @"")

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

/*
Text for button to remind the user to review later.
*/
#define APPIRATER_RATE_LATER @"Remind me later"

/*
Users will need to have the same version of your app installed for this many
Expand Down Expand Up @@ -118,10 +95,10 @@ extern NSString *const kAppiraterDeclinedToRate;
#define APPIRATER_TIME_BEFORE_REMINDING 1 // double

/*
'YES' will show the Appirater alert everytime. Useful for testing how your message
'1' 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.
*/
#define APPIRATER_DEBUG NO
#define APPIRATER_DEBUG 0

@interface Appirater : NSObject <UIAlertViewDelegate> {

Expand All @@ -130,14 +107,6 @@ extern NSString *const kAppiraterDeclinedToRate;

@property(nonatomic, retain) UIAlertView *ratingAlert;

/*
DEPRECATED: While still functional, it's better to use
appLaunched:(BOOL)canPromptForRating instead.

Calls [Appirater appLaunched:YES]. See appLaunched: for details of functionality.
*/
+ (void)appLaunched;

/*
Tells Appirater that the app has launched, and on devices that do NOT
support multitasking, the 'uses' count will be incremented. You should
Expand All @@ -151,7 +120,7 @@ extern NSString *const kAppiraterDeclinedToRate;
can also be triggered by appEnteredForeground: and userDidSignificantEvent:
(as long as you pass YES for canPromptForRating in those methods).
*/
+ (void)appLaunched:(BOOL)canPromptForRating;
+ (void)appLaunchedWithAppStoreID:(int)appID canPromptForRating:(BOOL)canPromptForRating;

/*
Tells Appirater that the app was brought to the foreground on multitasking
Expand Down
119 changes: 59 additions & 60 deletions Appirater.m
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@
NSString *templateReviewURL = @"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID";


NSBundle *appiraterBundle(void) {
static NSBundle* bundle = nil;
if (!bundle) {
NSString* path = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:kAppiraterBundleName];
bundle = [[NSBundle bundleWithPath:path] retain];
}
return bundle;
}


@interface Appirater (hidden)
- (BOOL)connectedToNetwork;
+ (Appirater*)sharedInstance;
Expand Down Expand Up @@ -92,32 +103,29 @@ - (BOOL)connectedToNetwork {

+ (Appirater*)sharedInstance {
static Appirater *appirater = nil;
if (appirater == nil)
{
@synchronized(self) {
if (appirater == nil) {
appirater = [[Appirater alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive) name:@"UIApplicationWillResignActiveNotification" object:nil];
}
}
}
static dispatch_once_t appiraterOnceToken;
dispatch_once(&appiraterOnceToken, ^{
appirater = [[Appirater alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive) name:UIApplicationWillResignActiveNotification object:nil];
});

return appirater;
}

- (void)showRatingAlert {
UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:APPIRATER_MESSAGE_TITLE
message:APPIRATER_MESSAGE
delegate:self
cancelButtonTitle:APPIRATER_CANCEL_BUTTON
otherButtonTitles:APPIRATER_RATE_BUTTON, APPIRATER_RATE_LATER, nil] autorelease];
UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:AppiraterLocalize(@"AppiraterTitle"), APPIRATER_APP_NAME]
message:[NSString stringWithFormat:AppiraterLocalize(@"AppiraterMessage"), APPIRATER_APP_NAME]
delegate:self
cancelButtonTitle:AppiraterLocalize(@"AppiraterCancelButton")
otherButtonTitles:[NSString stringWithFormat:AppiraterLocalize(@"AppiraterRateButton"), APPIRATER_APP_NAME], AppiraterLocalize(@"AppiraterRateLaterButton"), nil] autorelease];
self.ratingAlert = alertView;
[alertView show];
}

- (BOOL)ratingConditionsHaveBeenMet {
if (APPIRATER_DEBUG)
return YES;
#if APPIRATER_DEBUG
return YES;
#endif

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

Expand Down Expand Up @@ -168,8 +176,9 @@ - (void)incrementUseCount {
[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
}

if (APPIRATER_DEBUG)
NSLog(@"APPIRATER Tracking version: %@", trackingVersion);
#if APPIRATER_DEBUG
NSLog(@"APPIRATER Tracking version: %@", trackingVersion);
#endif

if ([trackingVersion isEqualToString:version])
{
Expand All @@ -185,8 +194,9 @@ - (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);
#endif
}
else
{
Expand Down Expand Up @@ -216,8 +226,9 @@ - (void)incrementSignificantEventCount {
[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
}

if (APPIRATER_DEBUG)
NSLog(@"APPIRATER Tracking version: %@", trackingVersion);
#if APPIRATER_DEBUG
NSLog(@"APPIRATER Tracking version: %@", trackingVersion);
#endif

if ([trackingVersion isEqualToString:version])
{
Expand All @@ -233,8 +244,9 @@ - (void)incrementSignificantEventCount {
int sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount];
sigEventCount++;
[userDefaults setInteger:sigEventCount forKey:kAppiraterSignificantEventCount];
if (APPIRATER_DEBUG)
NSLog(@"APPIRATER Significant event count: %d", sigEventCount);
#if APPIRATER_DEBUG
NSLog(@"APPIRATER Significant event count: %d", sigEventCount);
#endif
}
else
{
Expand Down Expand Up @@ -262,84 +274,71 @@ @implementation Appirater

@synthesize ratingAlert;

- (void)incrementAndRate:(NSNumber*)_canPromptForRating {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

- (void)incrementAndRate:(BOOL)canPromptForRating {
[self incrementUseCount];

if ([_canPromptForRating boolValue] == YES &&
if (canPromptForRating == YES &&
[self ratingConditionsHaveBeenMet] &&
[self connectedToNetwork])
{
[self performSelectorOnMainThread:@selector(showRatingAlert) withObject:nil waitUntilDone:NO];
}

[pool release];
}

- (void)incrementSignificantEventAndRate:(NSNumber*)_canPromptForRating {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

- (void)incrementSignificantEventAndRate:(BOOL)canPromptForRating {
[self incrementSignificantEventCount];

if ([_canPromptForRating boolValue] == YES &&
if (canPromptForRating == YES &&
[self ratingConditionsHaveBeenMet] &&
[self connectedToNetwork])
{
[self performSelectorOnMainThread:@selector(showRatingAlert) withObject:nil waitUntilDone:NO];
}

[pool release];
}

+ (void)appLaunched {
[Appirater appLaunched:YES];
}
static int appID;

+ (void)appLaunched:(BOOL)canPromptForRating {
NSNumber *_canPromptForRating = [[NSNumber alloc] initWithBool:canPromptForRating];
[NSThread detachNewThreadSelector:@selector(incrementAndRate:)
toTarget:[Appirater sharedInstance]
withObject:_canPromptForRating];
[_canPromptForRating release];
+ (void)appLaunchedWithAppStoreID:(int)anAppID canPromptForRating:(BOOL)canPromptForRating {
appID = anAppID;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
[[Appirater sharedInstance] incrementAndRate:canPromptForRating];
});
}

- (void)hideRatingAlert {
if (self.ratingAlert.visible) {
if (APPIRATER_DEBUG)
NSLog(@"APPIRATER Hiding Alert");
#if APPIRATER_DEBUG
NSLog(@"APPIRATER Hiding Alert");
#endif
[self.ratingAlert dismissWithClickedButtonIndex:-1 animated:NO];
}
}

+ (void)appWillResignActive {
if (APPIRATER_DEBUG)
NSLog(@"APPIRATER appWillResignActive");
#if APPIRATER_DEBUG
NSLog(@"APPIRATER appWillResignActive");
#endif
[[Appirater sharedInstance] hideRatingAlert];
}

+ (void)appEnteredForeground:(BOOL)canPromptForRating {
NSNumber *_canPromptForRating = [[NSNumber alloc] initWithBool:canPromptForRating];
[NSThread detachNewThreadSelector:@selector(incrementAndRate:)
toTarget:[Appirater sharedInstance]
withObject:_canPromptForRating];
[_canPromptForRating release];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
[[Appirater sharedInstance] incrementAndRate:canPromptForRating];
});
}

+ (void)userDidSignificantEvent:(BOOL)canPromptForRating {
NSNumber *_canPromptForRating = [[NSNumber alloc] initWithBool:canPromptForRating];
[NSThread detachNewThreadSelector:@selector(incrementSignificantEventAndRate:)
toTarget:[Appirater sharedInstance]
withObject:_canPromptForRating];
[_canPromptForRating release];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
[[Appirater sharedInstance] incrementSignificantEventAndRate:canPromptForRating];
});
}

+ (void)rateApp {
#if TARGET_IPHONE_SIMULATOR
NSLog(@"APPIRATER NOTE: iTunes App Store is not supported on the iOS simulator. Unable to open App Store page.");
#else
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%d", APPIRATER_APP_ID]];
NSString *reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%d", appID]];
[userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion];
[userDefaults synchronize];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:reviewURL]];
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ Getting Started
---------------
1. Add the Appirater code into your project
2. Add the `CFNetwork` and `SystemConfiguration` frameworks to your project
3. Call `[Appirater appLaunched:YES]` at the end of your app delegate's `application:didFinishLaunchingWithOptions:` method.
3. Call `[Appirater appLaunchedWithAppStoreID:APPIRATER_APP_ID canPromptForRating:YES]` at the end of your app delegate's `application:didFinishLaunchingWithOptions:` method, where `APPIRATER_APP_ID` is your Apple provided software id.
4. Call `[Appirater appEnteredForeground:YES]` in your app delegate's `applicationWillEnterForeground:` method.
5. (OPTIONAL) Call `[Appirater userDidSignificantEvent:YES]` when the user does something 'significant' in the app.
6. Finally, set the `APPIRATER_APP_ID` in `Appirater.h` to your Apple provided software id.

License
-------
Expand Down