Skip to content
Browse files

Merge pull request #91 from nathangreenstein/master

Added support for iOS 6's StoreKit
  • Loading branch information...
2 parents 1776888 + d7b529d commit 588ca15eb698a497ca3111ed24dc7119dc3fabeb @arashpayan committed Jan 12, 2013
Showing with 76 additions and 15 deletions.
  1. +12 −1 Appirater.h
  2. +57 −9 Appirater.m
  3. +2 −1 AppiraterDelegate.h
  4. +5 −4 README.md
View
13 Appirater.h
@@ -36,6 +36,7 @@
#import <Foundation/Foundation.h>
#import "AppiraterDelegate.h"
+#import <StoreKit/StoreKit.h>
extern NSString *const kAppiraterFirstUseDate;
extern NSString *const kAppiraterUseCount;
@@ -84,7 +85,7 @@ extern NSString *const kAppiraterReminderRequestDate;
*/
#define APPIRATER_RATE_LATER NSLocalizedStringFromTable(@"Remind me later", @"AppiraterLocalizable", nil)
-@interface Appirater : NSObject <UIAlertViewDelegate> {
+@interface Appirater : NSObject <UIAlertViewDelegate, SKStoreProductViewControllerDelegate> {
UIAlertView *ratingAlert;
}
@@ -154,6 +155,11 @@ extern NSString *const kAppiraterReminderRequestDate;
*/
+ (void)rateApp;
+/*
+ Tells Appirater to immediately close any open rating modals (e.g. StoreKit rating VCs).
+*/
++ (void)closeModal;
+
@end
@interface Appirater(Configuration)
@@ -213,6 +219,11 @@ extern NSString *const kAppiraterReminderRequestDate;
*/
+ (void)setDelegate:(id<AppiraterDelegate>)delegate;
+/*
+ Set whether or not Appirater uses animation (currently respected when pushing modal StoreKit rating VCs).
+ */
++ (void)setUsesAnimation:(BOOL)animation;
+
@end
View
66 Appirater.m
@@ -55,6 +55,9 @@
static double _timeBeforeReminding = 1;
static BOOL _debug = NO;
static id<AppiraterDelegate> _delegate;
+static BOOL _usesAnimation = TRUE;
+static UIStatusBarStyle _statusBarStyle;
+static BOOL _modalOpen = false;
@interface Appirater ()
- (BOOL)connectedToNetwork;
@@ -95,6 +98,15 @@ + (void) setDebug:(BOOL)debug {
+ (void)setDelegate:(id<AppiraterDelegate>)delegate{
_delegate = delegate;
}
++ (void)setUsesAnimation:(BOOL)animation {
+ _usesAnimation = animation;
+}
++ (void)setStatusBarStyle:(UIStatusBarStyle)style {
+ _statusBarStyle = style;
+}
++ (void)setModalOpen:(BOOL)open {
+ _modalOpen = open;
+}
- (BOOL)connectedToNetwork {
// Create zero addy
@@ -361,18 +373,36 @@ + (void)userDidSignificantEvent:(BOOL)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];
-
- // this URL Scheme should work in the iOS 6 App Store in addition to older stores
- NSString *reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%@", _appId]];
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion];
[userDefaults synchronize];
- [[UIApplication sharedApplication] openURL:[NSURL URLWithString:reviewURL]];
-#endif
+
+ //Use the in-app StoreKit view if available (iOS 6) and imported. This works in the simulator.
+ if (NSStringFromClass([SKStoreProductViewController class]) != nil) {
+
+ SKStoreProductViewController *storeViewController = [[SKStoreProductViewController alloc] init];
+ NSNumber *appId = [NSNumber numberWithInteger:_appId.integerValue];
+ [storeViewController loadProductWithParameters:@{SKStoreProductParameterITunesItemIdentifier:appId} completionBlock:nil];
+ storeViewController.delegate = self.sharedInstance;
+ [self.sharedInstance.delegate appiraterWillPresentModalView:self.sharedInstance animated:_usesAnimation];
+ [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:storeViewController animated:_usesAnimation completion:^{
+ [self setModalOpen:YES];
+ //Temporarily use a black status bar to match the StoreKit view.
+ [self setStatusBarStyle:[UIApplication sharedApplication].statusBarStyle];
+ [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:_usesAnimation];
+ }];
+
+ //Use the standard openUrl method if StoreKit is unavailable.
+ } else {
+
+ #if TARGET_IPHONE_SIMULATOR
+ NSLog(@"APPIRATER NOTE: iTunes App Store is not supported on the iOS simulator. Unable to open App Store page.");
+ #else
+ NSString *reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%@", _appId]];
+ [[UIApplication sharedApplication] openURL:[NSURL URLWithString:reviewURL]];
+ #endif
+ }
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
@@ -411,4 +441,22 @@ - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)butto
}
}
+//Delegate call from the StoreKit view.
+- (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController {
+ [Appirater closeModal];
+}
+
+//Close the in-app rating (StoreKit) view and restore the previous status bar style.
++ (void)closeModal {
+ if (_modalOpen) {
+ [[UIApplication sharedApplication]setStatusBarStyle:_statusBarStyle animated:_usesAnimation];
+ BOOL usedAnimation = _usesAnimation;
+ [self setModalOpen:NO];
+ [[UIApplication sharedApplication].keyWindow.rootViewController dismissViewControllerAnimated:_usesAnimation completion:^{
+ [self.sharedInstance.delegate appiraterDidDismissModalView:(Appirater *)self animated:usedAnimation];
+ }];
+ [self.class setStatusBarStyle:(UIStatusBarStyle)nil];
+ }
+}
+
@end
View
3 AppiraterDelegate.h
@@ -17,5 +17,6 @@
-(void)appiraterDidDeclineToRate:(Appirater *)appirater;
-(void)appiraterDidOptToRate:(Appirater *)appirater;
-(void)appiraterDidOptToRemindLater:(Appirater *)appirater;
-
+-(void)appiraterWillPresentModalView:(Appirater *)appirater animated:(BOOL)animated;
+-(void)appiraterDidDismissModalView:(Appirater *)appirater animated:(BOOL)animated;
@end
View
9 README.md
@@ -10,10 +10,11 @@ Getting Started
---------------
1. Add the Appirater code into your project.
2. Add the `CFNetwork` and `SystemConfiguration` frameworks to your project.
-3. Call `[Appirater setAppId:@"yourAppId"]` with the app id provided by Apple. A good place to do this is at the beginning of your app delegate's `application:didFinishLaunchingWithOptions:` method.
-4. Call `[Appirater appLaunched:YES]` at the end of your app delegate's `application:didFinishLaunchingWithOptions:` method.
-5. Call `[Appirater appEnteredForeground:YES]` in your app delegate's `applicationWillEnterForeground:` method.
-6. (OPTIONAL) Call `[Appirater userDidSignificantEvent:YES]` when the user does something 'significant' in the app.
+3. If you want to take advantage of [StoreKit's in-app rating view](http://developer.apple.com/library/ios/#documentation/StoreKit/Reference/SKITunesProductViewController_Ref/Introduction/Introduction.html) (iOS 6), add the `StoreKit` framework. Be sure to **change Required to Optional** for StoreKit in your target's Build Phases » Link Binary with Libraries section.
+4. Call `[Appirater setAppId:@"yourAppId"]` with the app id provided by Apple. A good place to do this is at the beginning of your app delegate's `application:didFinishLaunchingWithOptions:` method.
+5. Call `[Appirater appLaunched:YES]` at the end of your app delegate's `application:didFinishLaunchingWithOptions:` method.
+6. Call `[Appirater appEnteredForeground:YES]` in your app delegate's `applicationWillEnterForeground:` method.
+7. (OPTIONAL) Call `[Appirater userDidSignificantEvent:YES]` when the user does something 'significant' in the app.
Configuration
-------------

0 comments on commit 588ca15

Please sign in to comment.
Something went wrong with that request. Please try again.