Permalink
Browse files

Merge pull request #58 from robotmedia/master

Dynamic configuration + ARC
  • Loading branch information...
2 parents fe6c9a2 + f876e29 commit da20fe69967ce7b5d5b3de0ad89af335e78bde4a @arashpayan committed Aug 31, 2012
Showing with 119 additions and 75 deletions.
  1. +2 −0 .gitignore
  2. +68 −58 Appirater.h
  3. +48 −16 Appirater.m
  4. +1 −1 README.md
View
2 .gitignore
@@ -0,0 +1,2 @@
+
+.DS_Store
View
126 Appirater.h
@@ -45,12 +45,6 @@ extern NSString *const kAppiraterDeclinedToRate;
extern NSString *const kAppiraterReminderRequestDate;
/*
- Place your Apple generated software id here.
- */
-#define APPIRATER_APP_ID 301377083
-
-
-/*
Your localized app's name.
*/
#define APPIRATER_LOCALIZED_APP_NAME [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:(NSString *)kCFBundleNameKey]
@@ -89,64 +83,13 @@ extern NSString *const kAppiraterReminderRequestDate;
*/
#define APPIRATER_RATE_LATER NSLocalizedString(@"Remind me later", nil)
-/*
- Users will need to have the same version of your app installed for this many
- days before they will be prompted to rate it.
- */
-#define APPIRATER_DAYS_UNTIL_PROMPT 30 // double
-
-/*
- An example of a 'use' would be if the user launched the app. Bringing the app
- into the foreground (on devices that support it) would also be considered
- a 'use'. You tell Appirater about these events using the two methods:
- [Appirater appLaunched:]
- [Appirater appEnteredForeground:]
-
- Users need to 'use' the same version of the app this many times before
- before they will be prompted to rate it.
- */
-#define APPIRATER_USES_UNTIL_PROMPT 20 // integer
-
-/*
- A significant event can be anything you want to be in your app. In a
- telephone app, a significant event might be placing or receiving a call.
- In a game, it might be beating a level or a boss. This is just another
- layer of filtering that can be used to make sure that only the most
- loyal of your users are being prompted to rate you on the app store.
- If you leave this at a value of -1, then this won't be a criteria
- used for rating. To tell Appirater that the user has performed
- a significant event, call the method:
- [Appirater userDidSignificantEvent:];
- */
-#define APPIRATER_SIG_EVENTS_UNTIL_PROMPT -1 // integer
-
-/*
- 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.
- */
-#define APPIRATER_TIME_BEFORE_REMINDING 1 // double
-
-/*
- '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.
- */
-#define APPIRATER_DEBUG YES
@interface Appirater : NSObject <UIAlertViewDelegate> {
UIAlertView *ratingAlert;
}
-@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;
+@property(nonatomic, strong) UIAlertView *ratingAlert;
/*
Tells Appirater that the app has launched, and on devices that do NOT
@@ -207,3 +150,70 @@ extern NSString *const kAppiraterReminderRequestDate;
+ (void)rateApp;
@end
+
+@interface Appirater(Configuration)
+
+/*
+ Set your Apple generated software id here.
+ */
++ (void) setAppId:(NSString*)appId;
+
+/*
+ Users will need to have the same version of your app installed for this many
+ days before they will be prompted to rate it.
+ */
++ (void) setDaysUntilPrompt:(double)value;
+
+/*
+ An example of a 'use' would be if the user launched the app. Bringing the app
+ into the foreground (on devices that support it) would also be considered
+ a 'use'. You tell Appirater about these events using the two methods:
+ [Appirater appLaunched:]
+ [Appirater appEnteredForeground:]
+
+ Users need to 'use' the same version of the app this many times before
+ before they will be prompted to rate it.
+ */
++ (void) setUsesUntilPrompt:(NSInteger)value;
+
+/*
+ A significant event can be anything you want to be in your app. In a
+ telephone app, a significant event might be placing or receiving a call.
+ In a game, it might be beating a level or a boss. This is just another
+ layer of filtering that can be used to make sure that only the most
+ loyal of your users are being prompted to rate you on the app store.
+ If you leave this at a value of -1, then this won't be a criteria
+ used for rating. To tell Appirater that the user has performed
+ a significant event, call the method:
+ [Appirater userDidSignificantEvent:];
+ */
++ (void) setSignificantEventsUntilPrompt:(NSInteger)value;
+
+
+/*
+ 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.
+ */
++ (void) setTimeBeforeReminding:(double)value;
+
+/*
+ '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.
+ */
++ (void) setDebug:(BOOL)debug;
+
+@end
+
+
+@interface Appirater(Deprecated)
+
+/*
+ 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 __attribute__((deprecated));
+
+@end
View
64 Appirater.m
@@ -49,6 +49,13 @@
NSString *templateReviewURL = @"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID";
NSString *templateReviewURLiOS6 = @"itms-apps://itunes.apple.com/LANGUAGE/app/idAPP_ID";
+static NSString *_appId;
+static double _daysUntilPrompt = 30;
+static NSInteger _usesUntilPrompt = 20;
+static NSInteger _significantEventsUntilPrompt = -1;
+static double _timeBeforeReminding = 1;
+static BOOL _debug = NO;
+
@interface Appirater ()
- (BOOL)connectedToNetwork;
+ (Appirater*)sharedInstance;
@@ -62,6 +69,31 @@ @implementation Appirater
@synthesize ratingAlert;
++ (void) setAppId:(NSString *)appId {
+ _appId = appId;
+}
+
++ (void) setDaysUntilPrompt:(double)value {
+ _daysUntilPrompt = value;
+}
+
++ (void) setUsesUntilPrompt:(NSInteger)value {
+ _usesUntilPrompt = value;
+}
+
++ (void) setSignificantEventsUntilPrompt:(NSInteger)value {
+ _significantEventsUntilPrompt = value;
+}
+
++ (void) setTimeBeforeReminding:(double)value {
+ _timeBeforeReminding = value;
+}
+
++ (void) setDebug:(BOOL)debug {
+ _debug = debug;
+}
+
+
- (BOOL)connectedToNetwork {
// Create zero addy
struct sockaddr_in zeroAddress;
@@ -88,7 +120,7 @@ - (BOOL)connectedToNetwork {
NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"];
NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
- NSURLConnection *testConnection = [[[NSURLConnection alloc] initWithRequest:testRequest delegate:self] autorelease];
+ NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:self];
return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;
}
@@ -109,35 +141,35 @@ + (Appirater*)sharedInstance {
}
- (void)showRatingAlert {
- UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:APPIRATER_MESSAGE_TITLE
+ 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];
+ otherButtonTitles:APPIRATER_RATE_BUTTON, APPIRATER_RATE_LATER, nil];
self.ratingAlert = alertView;
[alertView show];
}
- (BOOL)ratingConditionsHaveBeenMet {
- if (APPIRATER_DEBUG)
+ if (_debug)
return YES;
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 timeUntilRate = 60 * 60 * 24 * _daysUntilPrompt;
if (timeSinceFirstLaunch < timeUntilRate)
return NO;
// check if the app has been used enough
int useCount = [userDefaults integerForKey:kAppiraterUseCount];
- if (useCount <= APPIRATER_USES_UNTIL_PROMPT)
+ if (useCount <= _usesUntilPrompt)
return NO;
// check if the user has done enough significant events
int sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount];
- if (sigEventCount <= APPIRATER_SIG_EVENTS_UNTIL_PROMPT)
+ if (sigEventCount <= _significantEventsUntilPrompt)
return NO;
// has the user previously declined to rate this version of the app?
@@ -151,7 +183,7 @@ - (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 timeUntilReminder = 60 * 60 * 24 * APPIRATER_TIME_BEFORE_REMINDING;
+ NSTimeInterval timeUntilReminder = 60 * 60 * 24 * _timeBeforeReminding;
if (timeSinceReminderRequest < timeUntilReminder)
return NO;
@@ -171,7 +203,7 @@ - (void)incrementUseCount {
[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
}
- if (APPIRATER_DEBUG)
+ if (_debug)
NSLog(@"APPIRATER Tracking version: %@", trackingVersion);
if ([trackingVersion isEqualToString:version])
@@ -188,7 +220,7 @@ - (void)incrementUseCount {
int useCount = [userDefaults integerForKey:kAppiraterUseCount];
useCount++;
[userDefaults setInteger:useCount forKey:kAppiraterUseCount];
- if (APPIRATER_DEBUG)
+ if (_debug)
NSLog(@"APPIRATER Use count: %d", useCount);
}
else
@@ -219,7 +251,7 @@ - (void)incrementSignificantEventCount {
[userDefaults setObject:version forKey:kAppiraterCurrentVersion];
}
- if (APPIRATER_DEBUG)
+ if (_debug)
NSLog(@"APPIRATER Tracking version: %@", trackingVersion);
if ([trackingVersion isEqualToString:version])
@@ -236,7 +268,7 @@ - (void)incrementSignificantEventCount {
int sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount];
sigEventCount++;
[userDefaults setInteger:sigEventCount forKey:kAppiraterSignificantEventCount];
- if (APPIRATER_DEBUG)
+ if (_debug)
NSLog(@"APPIRATER Significant event count: %d", sigEventCount);
}
else
@@ -295,14 +327,14 @@ + (void)appLaunched:(BOOL)canPromptForRating {
- (void)hideRatingAlert {
if (self.ratingAlert.visible) {
- if (APPIRATER_DEBUG)
+ if (_debug)
NSLog(@"APPIRATER Hiding Alert");
[self.ratingAlert dismissWithClickedButtonIndex:-1 animated:NO];
}
}
+ (void)appWillResignActive {
- if (APPIRATER_DEBUG)
+ if (_debug)
NSLog(@"APPIRATER appWillResignActive");
[[Appirater sharedInstance] hideRatingAlert];
}
@@ -330,12 +362,12 @@ + (void)rateApp {
// added work arround for wrong URL Scheme used in new App store on iOS 6
NSString *reviewURL;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0) {
- reviewURL = [templateReviewURLiOS6 stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%d", APPIRATER_APP_ID]];
+ reviewURL = [templateReviewURLiOS6 stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%@", _appId]];
reviewURL = [reviewURL stringByReplacingOccurrencesOfString:@"LANGUAGE" withString:[NSString stringWithFormat:@"%@", [[NSLocale preferredLanguages] objectAtIndex:0]]];
} else {
- reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%d", APPIRATER_APP_ID]];
+ reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%@", _appId]];
}
[userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion];
View
2 README.md
@@ -13,7 +13,7 @@ Getting Started
3. Call `[Appirater appLaunched:YES]` at the end of your app delegate's `application:didFinishLaunchingWithOptions:` method.
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.
+6. Finally, call `[Appirater setAppId:@"yourAppId"]` with your Apple provided software id.
License
-------

0 comments on commit da20fe6

Please sign in to comment.