diff options
Diffstat (limited to 'platform/iphone')
-rw-r--r-- | platform/iphone/Appirater.h | 200 | ||||
-rw-r--r-- | platform/iphone/Appirater.m | 732 | ||||
-rw-r--r-- | platform/iphone/AppiraterDelegate.h | 23 | ||||
-rw-r--r-- | platform/iphone/SCsub | 5 | ||||
-rw-r--r-- | platform/iphone/app_delegate.mm | 9 | ||||
-rw-r--r-- | platform/iphone/detect.py | 1 |
6 files changed, 0 insertions, 970 deletions
diff --git a/platform/iphone/Appirater.h b/platform/iphone/Appirater.h deleted file mode 100644 index 96dd30e7c7..0000000000 --- a/platform/iphone/Appirater.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - This file is part of Appirater. - - Copyright (c) 2010, Arash Payan - All rights reserved. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - */ -/* - * Appirater.h - * appirater - * - * Created by Arash Payan on 9/5/09. - * http://arashpayan.com - * Copyright 2010 Arash Payan. All rights reserved. - */ - -#import <Foundation/Foundation.h> -#import <UIKit/UIKit.h> - -extern NSString *const kAppiraterFirstUseDate; -extern NSString *const kAppiraterUseCount; -extern NSString *const kAppiraterSignificantEventCount; -extern NSString *const kAppiraterCurrentVersion; -extern NSString *const kAppiraterRatedCurrentVersion; -extern NSString *const kAppiraterDeclinedToRate; - -/* - Place your Apple generated software id here. - */ -#define APPIRATER_APP_ID 301377083 - -/* - 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] - -/* - This is the title of the message alert that users will see. - */ -#define APPIRATER_MESSAGE_TITLE [NSString stringWithFormat:@"Rate %@", APPIRATER_APP_NAME] - -/* - The text of the button that rejects reviewing the app. - */ -#define APPIRATER_CANCEL_BUTTON @"No, Thanks" - -/* - 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 - 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 NO - -@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:(int)p_app_id; - -/* - Tells Appirater that the app has launched, and on devices that do NOT - support multitasking, the 'uses' count will be incremented. You should - call this method at the end of your application delegate's - application:didFinishLaunchingWithOptions: method. - - If the app has been used enough to be rated (and enough significant events), - you can suppress the rating alert - by passing NO for canPromptForRating. The rating alert will simply be postponed - until it is called again with YES for canPromptForRating. The rating alert - can also be triggered by appEnteredForeground: and userDidSignificantEvent: - (as long as you pass YES for canPromptForRating in those methods). - */ -+ (void)appLaunched:(BOOL)canPromptForRating app_id:(int)p_app_id; - -/* - Tells Appirater that the app was brought to the foreground on multitasking - devices. You should call this method from the application delegate's - applicationWillEnterForeground: method. - - If the app has been used enough to be rated (and enough significant events), - you can suppress the rating alert - by passing NO for canPromptForRating. The rating alert will simply be postponed - until it is called again with YES for canPromptForRating. The rating alert - can also be triggered by appLaunched: and userDidSignificantEvent: - (as long as you pass YES for canPromptForRating in those methods). - */ -+ (void)appEnteredForeground:(BOOL)canPromptForRating; - -/* - Tells Appirater that the user performed a significant event. A significant - event is whatever you want it to be. If you're app is used to make VoIP - calls, then you might want to call this method whenever the user places - a call. If it's a game, you might want to call this whenever the user - beats a level boss. - - If the user has performed enough significant events and used the app enough, - you can suppress the rating alert by passing NO for canPromptForRating. The - rating alert will simply be postponed until it is called again with YES for - canPromptForRating. The rating alert can also be triggered by appLaunched: - and appEnteredForeground: (as long as you pass YES for canPromptForRating - in those methods). - */ -+ (void)userDidSignificantEvent:(BOOL)canPromptForRating; - -/* - Tells Appirater to open the App Store page where the user can specify a - rating for the app. Also records the fact that this has happened, so the - user won't be prompted again to rate the app. - - The only case where you should call this directly is if your app has an - explicit "Rate this app" command somewhere. In all other cases, don't worry - 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. - */ -+ (void)rateApp; - -@end diff --git a/platform/iphone/Appirater.m b/platform/iphone/Appirater.m deleted file mode 100644 index 951b892032..0000000000 --- a/platform/iphone/Appirater.m +++ /dev/null @@ -1,732 +0,0 @@ -/* - This file is part of Appirater. - - Copyright (c) 2012, Arash Payan - All rights reserved. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - */ -/* - * Appirater.m - * appirater - * - * Created by Arash Payan on 9/5/09. - * http://arashpayan.com - * Copyright 2012 Arash Payan. All rights reserved. - */ - -#import "Appirater.h" -#import <SystemConfiguration/SCNetworkReachability.h> -#include <netinet/in.h> - -#if ! __has_feature(objc_arc) -#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC). -#endif - -NSString *const kAppiraterFirstUseDate = @"kAppiraterFirstUseDate"; -NSString *const kAppiraterUseCount = @"kAppiraterUseCount"; -NSString *const kAppiraterSignificantEventCount = @"kAppiraterSignificantEventCount"; -NSString *const kAppiraterCurrentVersion = @"kAppiraterCurrentVersion"; -NSString *const kAppiraterRatedCurrentVersion = @"kAppiraterRatedCurrentVersion"; -NSString *const kAppiraterDeclinedToRate = @"kAppiraterDeclinedToRate"; -NSString *const kAppiraterReminderRequestDate = @"kAppiraterReminderRequestDate"; - -NSString *templateReviewURL = @"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID"; -NSString *templateReviewURLiOS7 = @"itms-apps://itunes.apple.com/app/idAPP_ID"; -NSString *templateReviewURLiOS8 = @"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=APP_ID&onlyLatestVersion=true&pageNumber=0&sortOrdering=1&type=Purple+Software"; - -static NSString *_appId; -static double _daysUntilPrompt = 30; -static NSInteger _usesUntilPrompt = 20; -static NSInteger _significantEventsUntilPrompt = -1; -static double _timeBeforeReminding = 1; -static BOOL _debug = NO; -#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 - static id<AppiraterDelegate> _delegate; -#else - __weak static id<AppiraterDelegate> _delegate; -#endif -static BOOL _usesAnimation = TRUE; -static UIStatusBarStyle _statusBarStyle; -static BOOL _modalOpen = false; -static BOOL _alwaysUseMainBundle = 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 *alertRateLaterTitle; -- (BOOL)connectedToNetwork; -+ (Appirater*)sharedInstance; -- (void)showPromptWithChecks:(BOOL)withChecks - displayRateLaterButton:(BOOL)displayRateLaterButton; -- (void)showRatingAlert:(BOOL)displayRateLaterButton; -- (void)showRatingAlert; -- (BOOL)ratingAlertIsAppropriate; -- (BOOL)ratingConditionsHaveBeenMet; -- (void)incrementUseCount; -- (void)hideRatingAlert; -@end - -@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) setCustomAlertTitle:(NSString *)title -{ - [self sharedInstance].alertTitle = title; -} - -+ (void) setCustomAlertMessage:(NSString *)message -{ - [self sharedInstance].alertMessage = message; -} - -+ (void) setCustomAlertCancelButtonTitle:(NSString *)cancelTitle -{ - [self sharedInstance].alertCancelTitle = cancelTitle; -} - -+ (void) setCustomAlertRateButtonTitle:(NSString *)rateTitle -{ - [self sharedInstance].alertRateTitle = rateTitle; -} - -+ (void) setCustomAlertRateLaterButtonTitle:(NSString *)rateLaterTitle -{ - [self sharedInstance].alertRateLaterTitle = rateLaterTitle; -} - -+ (void) setDebug:(BOOL)debug { - _debug = debug; -} -+ (void)setDelegate:(id<AppiraterDelegate>)delegate{ - _delegate = delegate; -} -+ (void)setUsesAnimation:(BOOL)animation { - _usesAnimation = animation; -} -+ (void)setOpenInAppStore:(BOOL)openInAppStore { - [Appirater sharedInstance].openInAppStore = openInAppStore; -} -+ (void)setStatusBarStyle:(UIStatusBarStyle)style { - _statusBarStyle = style; -} -+ (void)setModalOpen:(BOOL)open { - _modalOpen = open; -} -+ (void)setAlwaysUseMainBundle:(BOOL)alwaysUseMainBundle { - _alwaysUseMainBundle = alwaysUseMainBundle; -} - -+ (NSBundle *)bundle -{ - NSBundle *bundle; - - if (_alwaysUseMainBundle) { - bundle = [NSBundle mainBundle]; - } else { - NSURL *appiraterBundleURL = [[NSBundle mainBundle] URLForResource:@"Appirater" withExtension:@"bundle"]; - - if (appiraterBundleURL) { - // Appirater.bundle will likely only exist when used via CocoaPods - bundle = [NSBundle bundleWithURL:appiraterBundleURL]; - } else { - bundle = [NSBundle mainBundle]; - } - } - - return bundle; -} - -- (NSString *)alertTitle -{ - return _alertTitle ? _alertTitle : APPIRATER_MESSAGE_TITLE; -} - -- (NSString *)alertMessage -{ - return _alertMessage ? _alertMessage : APPIRATER_MESSAGE; -} - -- (NSString *)alertCancelTitle -{ - return _alertCancelTitle ? _alertCancelTitle : APPIRATER_CANCEL_BUTTON; -} - -- (NSString *)alertRateTitle -{ - return _alertRateTitle ? _alertRateTitle : APPIRATER_RATE_BUTTON; -} - -- (NSString *)alertRateLaterTitle -{ - return _alertRateLaterTitle ? _alertRateLaterTitle : APPIRATER_RATE_LATER; -} - -- (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (id)init { - self = [super init]; - if (self) { - if ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0) { - self.openInAppStore = YES; - } else { - self.openInAppStore = NO; - } - } - - return self; -} - -- (BOOL)connectedToNetwork { - // Create zero addy - struct sockaddr_in zeroAddress; - bzero(&zeroAddress, sizeof(zeroAddress)); - zeroAddress.sin_len = sizeof(zeroAddress); - zeroAddress.sin_family = AF_INET; - - // Recover reachability flags - SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress); - SCNetworkReachabilityFlags flags; - - Boolean didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags); - CFRelease(defaultRouteReachability); - - if (!didRetrieveFlags) - { - NSLog(@"Error. Could not recover network reachability flags"); - return NO; - } - - BOOL isReachable = flags & kSCNetworkFlagsReachable; - BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired; - BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection; - - 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]; - - return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO; -} - -+ (Appirater*)sharedInstance { - static Appirater *appirater = nil; - if (appirater == nil) - { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - appirater = [[Appirater alloc] init]; - appirater.delegate = _delegate; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive) name: - UIApplicationWillResignActiveNotification object:nil]; - }); - } - - return appirater; -} - -- (void)showRatingAlert:(BOOL)displayRateLaterButton { - UIAlertView *alertView = nil; - id <AppiraterDelegate> delegate = _delegate; - - if(delegate && [delegate respondsToSelector:@selector(appiraterShouldDisplayAlert:)] && ![delegate appiraterShouldDisplayAlert:self]) { - return; - } - - if (displayRateLaterButton) { - alertView = [[UIAlertView alloc] initWithTitle:self.alertTitle - message:self.alertMessage - delegate:self - cancelButtonTitle:self.alertCancelTitle - otherButtonTitles:self.alertRateTitle, self.alertRateLaterTitle, nil]; - } else { - alertView = [[UIAlertView alloc] initWithTitle:self.alertTitle - message:self.alertMessage - delegate:self - cancelButtonTitle:self.alertCancelTitle - otherButtonTitles:self.alertRateTitle, nil]; - } - - self.ratingAlert = alertView; - [alertView show]; - - if (delegate && [delegate respondsToSelector:@selector(appiraterDidDisplayAlert:)]) { - [delegate appiraterDidDisplayAlert:self]; - } -} - -- (void)showRatingAlert -{ - [self showRatingAlert:true]; -} - -// is this an ok time to show the alert? (regardless of whether the rating conditions have been met) -// -// things checked here: -// * connectivity with network -// * whether user has rated before -// * whether user has declined to rate -// * whether rating alert is currently showing visibly -// things NOT checked here: -// * time since first launch -// * number of uses of app -// * number of significant events -// * time since last reminder -- (BOOL)ratingAlertIsAppropriate { - return ([self connectedToNetwork] - && ![self userHasDeclinedToRate] - && !self.ratingAlert.visible - && ![self userHasRatedCurrentVersion]); -} - -// have the rating conditions been met/earned? (regardless of whether this would be a moment when it's appropriate to show a new rating alert) -// -// things checked here: -// * time since first launch -// * number of uses of app -// * number of significant events -// * time since last reminder -// things NOT checked here: -// * connectivity with network -// * whether user has rated before -// * whether user has declined to rate -// * whether rating alert is currently showing visibly -- (BOOL)ratingConditionsHaveBeenMet { - 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 * _daysUntilPrompt; - if (timeSinceFirstLaunch < timeUntilRate) - return NO; - - // check if the app has been used enough - NSInteger useCount = [userDefaults integerForKey:kAppiraterUseCount]; - if (useCount < _usesUntilPrompt) - return NO; - - // check if the user has done enough significant events - NSInteger sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount]; - if (sigEventCount < _significantEventsUntilPrompt) - return NO; - - // 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 * _timeBeforeReminding; - if (timeSinceReminderRequest < timeUntilReminder) - return NO; - - return YES; -} - -- (void)incrementUseCount { - // get the app's version - NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey]; - - // get the version number that we've been tracking - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - NSString *trackingVersion = [userDefaults stringForKey:kAppiraterCurrentVersion]; - if (trackingVersion == nil) - { - trackingVersion = version; - [userDefaults setObject:version forKey:kAppiraterCurrentVersion]; - } - - if (_debug) - NSLog(@"APPIRATER Tracking version: %@", trackingVersion); - - if ([trackingVersion isEqualToString:version]) - { - // check if the first use date has been set. if not, set it. - NSTimeInterval timeInterval = [userDefaults doubleForKey:kAppiraterFirstUseDate]; - if (timeInterval == 0) - { - timeInterval = [[NSDate date] timeIntervalSince1970]; - [userDefaults setDouble:timeInterval forKey:kAppiraterFirstUseDate]; - } - - // increment the use count - NSInteger useCount = [userDefaults integerForKey:kAppiraterUseCount]; - useCount++; - [userDefaults setInteger:useCount forKey:kAppiraterUseCount]; - if (_debug) - NSLog(@"APPIRATER Use count: %@", @(useCount)); - } - else - { - // it's a new version of the app, so restart tracking - [userDefaults setObject:version forKey:kAppiraterCurrentVersion]; - [userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterFirstUseDate]; - [userDefaults setInteger:1 forKey:kAppiraterUseCount]; - [userDefaults setInteger:0 forKey:kAppiraterSignificantEventCount]; - [userDefaults setBool:NO forKey:kAppiraterRatedCurrentVersion]; - [userDefaults setBool:NO forKey:kAppiraterDeclinedToRate]; - [userDefaults setDouble:0 forKey:kAppiraterReminderRequestDate]; - } - - [userDefaults synchronize]; -} - -- (void)incrementSignificantEventCount { - // get the app's version - NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey]; - - // get the version number that we've been tracking - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - NSString *trackingVersion = [userDefaults stringForKey:kAppiraterCurrentVersion]; - if (trackingVersion == nil) - { - trackingVersion = version; - [userDefaults setObject:version forKey:kAppiraterCurrentVersion]; - } - - if (_debug) - NSLog(@"APPIRATER Tracking version: %@", trackingVersion); - - if ([trackingVersion isEqualToString:version]) - { - // check if the first use date has been set. if not, set it. - NSTimeInterval timeInterval = [userDefaults doubleForKey:kAppiraterFirstUseDate]; - if (timeInterval == 0) - { - timeInterval = [[NSDate date] timeIntervalSince1970]; - [userDefaults setDouble:timeInterval forKey:kAppiraterFirstUseDate]; - } - - // increment the significant event count - NSInteger sigEventCount = [userDefaults integerForKey:kAppiraterSignificantEventCount]; - sigEventCount++; - [userDefaults setInteger:sigEventCount forKey:kAppiraterSignificantEventCount]; - if (_debug) - NSLog(@"APPIRATER Significant event count: %@", @(sigEventCount)); - } - else - { - // it's a new version of the app, so restart tracking - [userDefaults setObject:version forKey:kAppiraterCurrentVersion]; - [userDefaults setDouble:0 forKey:kAppiraterFirstUseDate]; - [userDefaults setInteger:0 forKey:kAppiraterUseCount]; - [userDefaults setInteger:1 forKey:kAppiraterSignificantEventCount]; - [userDefaults setBool:NO forKey:kAppiraterRatedCurrentVersion]; - [userDefaults setBool:NO forKey:kAppiraterDeclinedToRate]; - [userDefaults setDouble:0 forKey:kAppiraterReminderRequestDate]; - } - - [userDefaults synchronize]; -} - -- (void)incrementAndRate:(BOOL)canPromptForRating { - [self incrementUseCount]; - - if (canPromptForRating && - [self ratingConditionsHaveBeenMet] && - [self ratingAlertIsAppropriate]) - { - dispatch_async(dispatch_get_main_queue(), - ^{ - [self showRatingAlert]; - }); - } -} - -- (void)incrementSignificantEventAndRate:(BOOL)canPromptForRating { - [self incrementSignificantEventCount]; - - if (canPromptForRating && - [self ratingConditionsHaveBeenMet] && - [self ratingAlertIsAppropriate]) - { - dispatch_async(dispatch_get_main_queue(), - ^{ - [self showRatingAlert]; - }); - } -} - -- (BOOL)userHasDeclinedToRate { - return [[NSUserDefaults standardUserDefaults] boolForKey:kAppiraterDeclinedToRate]; -} - -- (BOOL)userHasRatedCurrentVersion { - return [[NSUserDefaults standardUserDefaults] boolForKey:kAppiraterRatedCurrentVersion]; -} - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-implementations" -+ (void)appLaunched { - [Appirater appLaunched:YES]; -} -#pragma GCC diagnostic pop - -+ (void)appLaunched:(BOOL)canPromptForRating { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), - ^{ - Appirater *a = [Appirater sharedInstance]; - if (_debug) { - dispatch_async(dispatch_get_main_queue(), - ^{ - [a showRatingAlert]; - }); - } else { - [a incrementAndRate:canPromptForRating]; - } - }); -} - -- (void)hideRatingAlert { - if (self.ratingAlert.visible) { - if (_debug) - NSLog(@"APPIRATER Hiding Alert"); - [self.ratingAlert dismissWithClickedButtonIndex:-1 animated:NO]; - } -} - -+ (void)appWillResignActive { - if (_debug) - NSLog(@"APPIRATER appWillResignActive"); - [[Appirater sharedInstance] hideRatingAlert]; -} - -+ (void)appEnteredForeground:(BOOL)canPromptForRating { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), - ^{ - [[Appirater sharedInstance] incrementAndRate:canPromptForRating]; - }); -} - -+ (void)userDidSignificantEvent:(BOOL)canPromptForRating { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), - ^{ - [[Appirater sharedInstance] incrementSignificantEventAndRate:canPromptForRating]; - }); -} - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-implementations" -+ (void)showPrompt { - [Appirater tryToShowPrompt]; -} -#pragma GCC diagnostic pop - -+ (void)tryToShowPrompt { - [[Appirater sharedInstance] showPromptWithChecks:true - displayRateLaterButton:true]; -} - -+ (void)forceShowPrompt:(BOOL)displayRateLaterButton { - [[Appirater sharedInstance] showPromptWithChecks:false - displayRateLaterButton:displayRateLaterButton]; -} - -- (void)showPromptWithChecks:(BOOL)withChecks - displayRateLaterButton:(BOOL)displayRateLaterButton { - if (withChecks == NO || [self ratingAlertIsAppropriate]) { - [self showRatingAlert:displayRateLaterButton]; - } -} - -+ (id)getRootViewController { - UIWindow *window = [[UIApplication sharedApplication] keyWindow]; - if (window.windowLevel != UIWindowLevelNormal) { - NSArray *windows = [[UIApplication sharedApplication] windows]; - for(window in windows) { - if (window.windowLevel == UIWindowLevelNormal) { - break; - } - } - } - - return [Appirater iterateSubViewsForViewController:window]; // iOS 8+ deep traverse -} - -+ (id)iterateSubViewsForViewController:(UIView *) parentView { - for (UIView *subView in [parentView subviews]) { - UIResponder *responder = [subView nextResponder]; - if([responder isKindOfClass:[UIViewController class]]) { - return [self topMostViewController: (UIViewController *) responder]; - } - id found = [Appirater iterateSubViewsForViewController:subView]; - if( nil != found) { - return found; - } - } - return nil; -} - -+ (UIViewController *) topMostViewController: (UIViewController *) controller { - BOOL isPresenting = NO; - do { - // this path is called only on iOS 6+, so -presentedViewController is fine here. - UIViewController *presented = [controller presentedViewController]; - isPresenting = presented != nil; - if(presented != nil) { - controller = presented; - } - - } while (isPresenting); - - return controller; -} - -+ (void)rateApp { - - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - [userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion]; - [userDefaults synchronize]; - - //Use the in-app StoreKit view if available (iOS 6) and imported. This works in the simulator. - if (![Appirater sharedInstance].openInAppStore && 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; - - id <AppiraterDelegate> delegate = self.sharedInstance.delegate; - if ([delegate respondsToSelector:@selector(appiraterWillPresentModalView:animated:)]) { - [delegate appiraterWillPresentModalView:self.sharedInstance animated:_usesAnimation]; - } - [[self getRootViewController] presentViewController:storeViewController animated:_usesAnimation completion:^{ - [self setModalOpen:YES]; - //Temporarily use a black status bar to match the StoreKit view. - [self setStatusBarStyle:[UIApplication sharedApplication].statusBarStyle]; -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 - [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent animated:_usesAnimation]; -#endif - }]; - - //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]]; - - // iOS 7 needs a different templateReviewURL @see https://github.com/arashpayan/appirater/issues/131 - // Fixes condition @see https://github.com/arashpayan/appirater/issues/205 - if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 && [[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) { - reviewURL = [templateReviewURLiOS7 stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%@", _appId]]; - } - // iOS 8 needs a different templateReviewURL also @see https://github.com/arashpayan/appirater/issues/182 - else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) - { - reviewURL = [templateReviewURLiOS8 stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%@", _appId]]; - } - - [[UIApplication sharedApplication] openURL:[NSURL URLWithString:reviewURL]]; - #endif - } -} - -- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - - id <AppiraterDelegate> delegate = _delegate; - - switch (buttonIndex) { - case 0: - { - // they don't want to rate it - [userDefaults setBool:YES forKey:kAppiraterDeclinedToRate]; - [userDefaults synchronize]; - if(delegate && [delegate respondsToSelector:@selector(appiraterDidDeclineToRate:)]){ - [delegate appiraterDidDeclineToRate:self]; - } - break; - } - case 1: - { - // they want to rate it - [Appirater rateApp]; - if(delegate&& [delegate respondsToSelector:@selector(appiraterDidOptToRate:)]){ - [delegate appiraterDidOptToRate:self]; - } - break; - } - case 2: - // remind them later - [userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterReminderRequestDate]; - [userDefaults synchronize]; - if(delegate && [delegate respondsToSelector:@selector(appiraterDidOptToRemindLater:)]){ - [delegate appiraterDidOptToRemindLater:self]; - } - break; - default: - break; - } -} - -//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]; - - // get the top most controller (= the StoreKit Controller) and dismiss it - UIViewController *presentingController = [UIApplication sharedApplication].keyWindow.rootViewController; - presentingController = [self topMostViewController: presentingController]; - [presentingController dismissViewControllerAnimated:_usesAnimation completion:^{ - id <AppiraterDelegate> delegate = self.sharedInstance.delegate; - if ([delegate respondsToSelector:@selector(appiraterDidDismissModalView:animated:)]) { - [delegate appiraterDidDismissModalView:(Appirater *)self animated:usedAnimation]; - } - }]; - [self.class setStatusBarStyle:(UIStatusBarStyle)nil]; - } -} - -@end diff --git a/platform/iphone/AppiraterDelegate.h b/platform/iphone/AppiraterDelegate.h deleted file mode 100644 index cbe0cfad5b..0000000000 --- a/platform/iphone/AppiraterDelegate.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// AppiraterDelegate.h -// Banana Stand -// -// Created by Robert Haining on 9/25/12. -// Copyright (c) 2012 News.me. All rights reserved. -// - -#import <Foundation/Foundation.h> - -@class Appirater; - -@protocol AppiraterDelegate <NSObject> - -@optional --(BOOL)appiraterShouldDisplayAlert:(Appirater *)appirater; --(void)appiraterDidDisplayAlert:(Appirater *)appirater; --(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 diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub index 38f789259c..5d3267cff3 100644 --- a/platform/iphone/SCsub +++ b/platform/iphone/SCsub @@ -15,7 +15,6 @@ iphone_lib = [ 'game_center.mm', 'in_app_store.mm', 'icloud.mm', - #'Appirater.m', 'ios.mm', ] @@ -30,10 +29,6 @@ if env['ios_gles22_override'] == "yes": env_ios.Append(CPPFLAGS=['-DGLES2_OVERRIDE']) -# if env['ios_appirater'] == "yes": -# env_ios.Append(CPPFLAGS=['-DAPPIRATER_ENABLED']) - - obj = env_ios.Object('godot_iphone.cpp') prog = None diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm index 1c47801b8e..00bb4b9fad 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/iphone/app_delegate.mm @@ -52,10 +52,6 @@ #define kRenderingFrequency 60 #define kAccelerometerFrequency 100.0 // Hz -#ifdef APPIRATER_ENABLED -#import "Appirater.h" -#endif - Error _shell_open(String); void _set_keep_screen_on(bool p_enabled); @@ -188,11 +184,6 @@ static int frame_count = 0; Main::start(); ++frame_count; - #ifdef APPIRATER_ENABLED - int aid = GlobalConfig::get_singleton()->get("ios/app_id"); - [Appirater appLaunched:YES app_id:aid]; - #endif - }; break; // no fallthrough default: { diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index 20fa45d708..fa6082a5a7 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -30,7 +30,6 @@ def get_opts(): ('store_kit', 'Support for in-app store', 'yes'), ('icloud', 'Support for iCloud', 'yes'), ('ios_gles22_override', 'Force GLES2.0 on iOS', 'yes'), - ('ios_appirater', 'Enable Appirater', 'no'), ('ios_exceptions', 'Use exceptions when compiling on playbook', 'yes'), ('ios_triple', 'Triple for ios toolchain', ''), ('ios_sim', 'Build simulator binary', 'no'), |