| 
							
								 | 
							
							//
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  iRate.m
 | 
						
						
						
						
							 | 
							
								 | 
							
							//
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  Version 1.11.4
 | 
						
						
						
						
							 | 
							
								 | 
							
							//
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  Created by Nick Lockwood on 26/01/2011.
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  Copyright 2011 Charcoal Design
 | 
						
						
						
						
							 | 
							
								 | 
							
							//
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  Distributed under the permissive zlib license
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  Get the latest version from here:
 | 
						
						
						
						
							 | 
							
								 | 
							
							//
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  https://github.com/nicklockwood/iRate
 | 
						
						
						
						
							 | 
							
								 | 
							
							//
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  This software is provided 'as-is', without any express or implied
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  warranty.  In no event will the authors be held liable for any damages
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  arising from the use of this software.
 | 
						
						
						
						
							 | 
							
								 | 
							
							//
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  Permission is granted to anyone to use this software for any purpose,
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  including commercial applications, and to alter it and redistribute it
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  freely, subject to the following restrictions:
 | 
						
						
						
						
							 | 
							
								 | 
							
							//
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  1. The origin of this software must not be misrepresented; you must not
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  claim that you wrote the original software. If you use this software
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  in a product, an acknowledgment in the product documentation would be
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  appreciated but is not required.
 | 
						
						
						
						
							 | 
							
								 | 
							
							//
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  2. Altered source versions must be plainly marked as such, and must not be
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  misrepresented as being the original software.
 | 
						
						
						
						
							 | 
							
								 | 
							
							//
 | 
						
						
						
						
							 | 
							
								 | 
							
							//  3. This notice may not be removed or altered from any source distribution.
 | 
						
						
						
						
							 | 
							
								 | 
							
							//
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#import "iRate.h"
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#import <Availability.h>
 | 
						
						
						
						
							 | 
							
								 | 
							
							#if !__has_feature(objc_arc)
 | 
						
						
						
						
							 | 
							
								 | 
							
							#error This class requires automatic reference counting
 | 
						
						
						
						
							 | 
							
								 | 
							
							#endif
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							// Unknown diagnostic
 | 
						
						
						
						
							 | 
							
								 | 
							
							// #pragma clang diagnostic ignored "-Wreceiver-is-weak"
 | 
						
						
						
						
							 | 
							
								 | 
							
							#pragma clang diagnostic ignored "-Warc-repeated-use-of-weak"
 | 
						
						
						
						
							 | 
							
								 | 
							
							#pragma clang diagnostic ignored "-Wobjc-missing-property-synthesis"
 | 
						
						
						
						
							 | 
							
								 | 
							
							#pragma clang diagnostic ignored "-Wdirect-ivar-access"
 | 
						
						
						
						
							 | 
							
								 | 
							
							#pragma clang diagnostic ignored "-Wunused-macros"
 | 
						
						
						
						
							 | 
							
								 | 
							
							#pragma clang diagnostic ignored "-Wconversion"
 | 
						
						
						
						
							 | 
							
								 | 
							
							#pragma clang diagnostic ignored "-Wformat-nonliteral"
 | 
						
						
						
						
							 | 
							
								 | 
							
							#pragma clang diagnostic ignored "-Wselector"
 | 
						
						
						
						
							 | 
							
								 | 
							
							#pragma clang diagnostic ignored "-Wgnu"
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSUInteger const iRateAppStoreGameGenreID = 6014;
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateErrorDomain          = @"iRateErrorDomain";
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateMessageTitleKey  = @"iRateMessageTitle";
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateAppMessageKey    = @"iRateAppMessage";
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateGameMessageKey   = @"iRateGameMessage";
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateUpdateMessageKey = @"iRateUpdateMessage";
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateCancelButtonKey  = @"iRateCancelButton";
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateRemindButtonKey  = @"iRateRemindButton";
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateRateButtonKey    = @"iRateRateButton";
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateCouldNotConnectToAppStore       = @"iRateCouldNotConnectToAppStore";
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateDidDetectAppUpdate              = @"iRateDidDetectAppUpdate";
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateDidPromptForRating              = @"iRateDidPromptForRating";
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateUserDidAttemptToRateApp         = @"iRateUserDidAttemptToRateApp";
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateUserDidDeclineToRateApp         = @"iRateUserDidDeclineToRateApp";
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateUserDidRequestReminderToRateApp = @"iRateUserDidRequestReminderToRateApp";
 | 
						
						
						
						
							 | 
							
								 | 
							
							NSString *const iRateDidOpenAppStore                 = @"iRateDidOpenAppStore";
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							static NSString *const iRateAppStoreIDKey      = @"iRateAppStoreID";
 | 
						
						
						
						
							 | 
							
								 | 
							
							static NSString *const iRateRatedVersionKey    = @"iRateRatedVersionChecked";
 | 
						
						
						
						
							 | 
							
								 | 
							
							static NSString *const iRateDeclinedVersionKey = @"iRateDeclinedVersion";
 | 
						
						
						
						
							 | 
							
								 | 
							
							static NSString *const iRateLastRemindedKey    = @"iRateLastReminded";
 | 
						
						
						
						
							 | 
							
								 | 
							
							static NSString *const iRateLastVersionUsedKey = @"iRateLastVersionUsed";
 | 
						
						
						
						
							 | 
							
								 | 
							
							static NSString *const iRateFirstUsedKey       = @"iRateFirstUsed";
 | 
						
						
						
						
							 | 
							
								 | 
							
							static NSString *const iRateUseCountKey        = @"iRateUseCount";
 | 
						
						
						
						
							 | 
							
								 | 
							
							static NSString *const iRateEventCountKey      = @"iRateEventCount";
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							static NSString *const iRateMacAppStoreBundleID = @"com.apple.appstore";
 | 
						
						
						
						
							 | 
							
								 | 
							
							static NSString *const iRateAppLookupURLFormat  = @"https://itunes.apple.com/%@/lookup";
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							static NSString *const iRateiOSAppStoreURLScheme = @"itms-apps";
 | 
						
						
						
						
							 | 
							
								 | 
							
							static NSString *const iRateiOSAppStoreURLFormat = @"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/"
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                   @"viewContentsUserReviews?type=Purple+Software&id=%@&pageNumber=0&"
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                   @"sortOrdering=2&mt=8";
 | 
						
						
						
						
							 | 
							
								 | 
							
							static NSString *const iRateiOS7AppStoreURLFormat = @"itms-apps://itunes.apple.com/app/id%@";
 | 
						
						
						
						
							 | 
							
								 | 
							
							static NSString *const iRateMacAppStoreURLFormat  = @"macappstore://itunes.apple.com/app/id%@";
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#define SECONDS_IN_A_DAY 86400.0
 | 
						
						
						
						
							 | 
							
								 | 
							
							#define SECONDS_IN_A_WEEK 604800.0
 | 
						
						
						
						
							 | 
							
								 | 
							
							#define MAC_APP_STORE_REFRESH_DELAY 5.0
 | 
						
						
						
						
							 | 
							
								 | 
							
							#define REQUEST_TIMEOUT 60.0
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							@implementation NSObject (iRate)
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)iRateCouldNotConnectToAppStore:(__unused NSError *)error {
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)iRateDidDetectAppUpdate {
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (BOOL)iRateShouldPromptForRating {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)iRateDidPromptForRating {
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)iRateUserDidAttemptToRateApp {
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)iRateUserDidDeclineToRateApp {
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)iRateUserDidRequestReminderToRateApp {
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (BOOL)iRateShouldOpenAppStore {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)iRateDidOpenAppStore {
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							@end
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							@interface iRate ()
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							@property (nonatomic, strong) id visibleAlert;
 | 
						
						
						
						
							 | 
							
								 | 
							
							@property (nonatomic, assign) BOOL checkingForPrompt;
 | 
						
						
						
						
							 | 
							
								 | 
							
							@property (nonatomic, assign) BOOL checkingForAppStoreID;
 | 
						
						
						
						
							 | 
							
								 | 
							
							@property (nonatomic, assign) BOOL shouldPreventPromptAtNextTest;
 | 
						
						
						
						
							 | 
							
								 | 
							
							@property (nonatomic) BOOL hasPromptedAtLaunch;
 | 
						
						
						
						
							 | 
							
								 | 
							
							@property (nonatomic) BOOL hasQueuedSynchronize;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							@end
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							@implementation iRate
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							// SIGNAL HACK
 | 
						
						
						
						
							 | 
							
								 | 
							
							// Disabled in Signal. We don't want to prompt users who haven't registered, even if it has been
 | 
						
						
						
						
							 | 
							
								 | 
							
							// a while since they installed. ~mjk
 | 
						
						
						
						
							 | 
							
								 | 
							
							//+ (void)load {
 | 
						
						
						
						
							 | 
							
								 | 
							
							//    [self performSelectorOnMainThread:@selector(sharedInstance) withObject:nil waitUntilDone:NO];
 | 
						
						
						
						
							 | 
							
								 | 
							
							//}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							+ (instancetype)sharedInstance {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static iRate *sharedInstance = nil;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (sharedInstance == nil) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        sharedInstance = [(iRate *)[self alloc] init];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return sharedInstance;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (NSString *)localizedStringForKey:(NSString *)key withDefault:(NSString *)defaultString {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    static NSBundle *bundle = nil;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (bundle == nil) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSString *bundlePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"iRate" ofType:@"bundle"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (self.useAllAvailableLanguages) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            bundle             = [NSBundle bundleWithPath:bundlePath];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSString *language = [[NSLocale preferredLanguages] count] ? [NSLocale preferredLanguages][0] : @"en";
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (![[bundle localizations] containsObject:language]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                language = [language componentsSeparatedByString:@"-"][0];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if ([[bundle localizations] containsObject:language]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                bundlePath = [bundle pathForResource:language ofType:@"lproj"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        bundle = [NSBundle bundleWithPath:bundlePath] ?: [NSBundle mainBundle];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    defaultString = [bundle localizedStringForKey:key value:defaultString table:nil];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [[NSBundle mainBundle] localizedStringForKey:key value:defaultString table:nil];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (iRate *)init {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if ((self = [super init])) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							#if TARGET_OS_IPHONE
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // register for iphone application events
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (&UIApplicationWillEnterForegroundNotification) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [[NSNotificationCenter defaultCenter] addObserver:self
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                     selector:@selector(applicationWillEnterForeground)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                         name:UIApplicationWillEnterForegroundNotification
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                       object:nil];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [[NSNotificationCenter defaultCenter] addObserver:self
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                     selector:@selector(applicationDidBecomeActive)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                         name:UIApplicationDidBecomeActiveNotification
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                       object:nil];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#endif
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // get country
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.appStoreCountry = [(NSLocale *)[NSLocale currentLocale] objectForKey:NSLocaleCountryCode];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if ([self.appStoreCountry isEqualToString:@"150"]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            self.appStoreCountry = @"eu";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        } else if (!self.appStoreCountry ||
 | 
						
						
						
						
							 | 
							
								 | 
							
							                   [[self.appStoreCountry stringByReplacingOccurrencesOfString:@"[A-Za-z]{2}"
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                                    withString:@""
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                                       options:NSRegularExpressionSearch
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                                         range:NSMakeRange(0, 2)] length]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            self.appStoreCountry = @"us";
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // application version (use short version preferentially)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.applicationVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if ([self.applicationVersion length] == 0) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            self.applicationVersion =
 | 
						
						
						
						
							 | 
							
								 | 
							
							                [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // localised application name
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.applicationName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if ([self.applicationName length] == 0) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            self.applicationName = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleNameKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // bundle id
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.applicationBundleID = [[NSBundle mainBundle] bundleIdentifier];
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // default settings
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.useAllAvailableLanguages          = YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.promptForNewVersionIfUserRated    = NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.onlyPromptIfLatestVersion         = YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.onlyPromptIfMainWindowIsAvailable = YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.promptAtLaunch                    = YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.usesUntilPrompt                   = 10;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.eventsUntilPrompt                 = 10;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.daysUntilPrompt                   = 10.0f;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.usesPerWeekForPrompt              = 0.0f;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.remindPeriod                      = 1.0f;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.verboseLogging                    = NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.previewMode                       = NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.shouldPreventPromptAtNextTest     = NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#if DEBUG
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // enable verbose logging in debug mode
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.verboseLogging = YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSLog(@"iRate verbose logging enabled.");
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#endif
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // app launched
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self performSelectorOnMainThread:@selector(applicationLaunched) withObject:nil waitUntilDone:NO];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return self;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (id<iRateDelegate>)delegate {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (_delegate == nil) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							#if TARGET_OS_IPHONE
 | 
						
						
						
						
							 | 
							
								 | 
							
							#define APP_CLASS UIApplication
 | 
						
						
						
						
							 | 
							
								 | 
							
							#else
 | 
						
						
						
						
							 | 
							
								 | 
							
							#define APP_CLASS NSApplication
 | 
						
						
						
						
							 | 
							
								 | 
							
							#endif
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        _delegate = (id<iRateDelegate>)[[APP_CLASS sharedApplication] delegate];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return _delegate;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (NSString *)messageTitle {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [_messageTitle ?: [self localizedStringForKey:iRateMessageTitleKey withDefault:@"Rate %@"]
 | 
						
						
						
						
							 | 
							
								 | 
							
							        stringByReplacingOccurrencesOfString:@"%@"
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                  withString:self.applicationName];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (NSString *)message {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    NSString *message = _message;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (!message) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        message = (self.appStoreGenreID == iRateAppStoreGameGenreID)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                      ? [self localizedStringForKey:iRateGameMessageKey
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                        withDefault:@"If you enjoy playing %@, would you mind taking a moment to rate "
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                    @"it? It won’t take more than a minute. Thanks for your support!"]
 | 
						
						
						
						
							 | 
							
								 | 
							
							                      : [self localizedStringForKey:iRateAppMessageKey
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                        withDefault:@"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!"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [message stringByReplacingOccurrencesOfString:@"%@" withString:self.applicationName];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (NSString *)updateMessage {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    NSString *updateMessage = _updateMessage;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (!updateMessage) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        updateMessage = [self localizedStringForKey:iRateUpdateMessageKey withDefault:self.message];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [updateMessage stringByReplacingOccurrencesOfString:@"%@" withString:self.applicationName];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (NSString *)cancelButtonLabel {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return _cancelButtonLabel ?: [self localizedStringForKey:iRateCancelButtonKey withDefault:@"No, Thanks"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (NSString *)rateButtonLabel {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return _rateButtonLabel ?: [self localizedStringForKey:iRateRateButtonKey withDefault:@"Rate It Now"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (NSString *)remindButtonLabel {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return _remindButtonLabel ?: [self localizedStringForKey:iRateRemindButtonKey withDefault:@"Remind Me Later"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (NSURL *)ratingsURL {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (_ratingsURL) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return _ratingsURL;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (!self.appStoreID && self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSLog(@"iRate could not find the App Store ID for this application. If the application is not intended for App "
 | 
						
						
						
						
							 | 
							
								 | 
							
							              @"Store release then you must specify a custom ratingsURL.");
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    NSString *URLString;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#if TARGET_OS_IPHONE
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    float iOSVersion = [[UIDevice currentDevice].systemVersion floatValue];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (iOSVersion >= 7.0f && iOSVersion < 7.1f) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        URLString = iRateiOS7AppStoreURLFormat;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    } else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        URLString = iRateiOSAppStoreURLFormat;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#else
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    URLString = iRateMacAppStoreURLFormat;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#endif
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [NSURL URLWithString:[NSString stringWithFormat:URLString, @(self.appStoreID)]];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (NSUInteger)appStoreID {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return _appStoreID
 | 
						
						
						
						
							 | 
							
								 | 
							
							               ?: [[[NSUserDefaults standardUserDefaults] objectForKey:iRateAppStoreIDKey] unsignedIntegerValue];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (NSDate *)firstUsed {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [[NSUserDefaults standardUserDefaults] objectForKey:iRateFirstUsedKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)setFirstUsed:(NSDate *)date {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [[NSUserDefaults standardUserDefaults] setObject:date forKey:iRateFirstUsedKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self synchronizeWhenSafeToDoSo];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (NSDate *)lastReminded {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [[NSUserDefaults standardUserDefaults] objectForKey:iRateLastRemindedKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)setLastReminded:(NSDate *)date {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [[NSUserDefaults standardUserDefaults] setObject:date forKey:iRateLastRemindedKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self synchronizeWhenSafeToDoSo];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (NSUInteger)usesCount {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [[NSUserDefaults standardUserDefaults] integerForKey:iRateUseCountKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)setUsesCount:(NSUInteger)count {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [[NSUserDefaults standardUserDefaults] setInteger:(NSInteger)count forKey:iRateUseCountKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self synchronizeWhenSafeToDoSo];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (NSUInteger)eventCount {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [[NSUserDefaults standardUserDefaults] integerForKey:iRateEventCountKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)setEventCount:(NSUInteger)count {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [[NSUserDefaults standardUserDefaults] setInteger:(NSInteger)count forKey:iRateEventCountKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self synchronizeWhenSafeToDoSo];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (float)usesPerWeek {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return (float)self.usesCount / ([[NSDate date] timeIntervalSinceDate:self.firstUsed] / SECONDS_IN_A_WEEK);
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (BOOL)declinedThisVersion {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [[[NSUserDefaults standardUserDefaults] objectForKey:iRateDeclinedVersionKey]
 | 
						
						
						
						
							 | 
							
								 | 
							
							        isEqualToString:self.applicationVersion];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)setDeclinedThisVersion:(BOOL)declined {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [[NSUserDefaults standardUserDefaults] setObject:(declined ? self.applicationVersion : nil)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                              forKey:iRateDeclinedVersionKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self synchronizeWhenSafeToDoSo];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (BOOL)declinedAnyVersion {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [(NSString *)[[NSUserDefaults standardUserDefaults] objectForKey:iRateDeclinedVersionKey] length] != 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (BOOL)ratedVersion:(NSString *)version {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [[[NSUserDefaults standardUserDefaults] objectForKey:iRateRatedVersionKey] isEqualToString:version];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (BOOL)ratedThisVersion {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [self ratedVersion:self.applicationVersion];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)setRatedThisVersion:(BOOL)rated {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [[NSUserDefaults standardUserDefaults] setObject:(rated ? self.applicationVersion : nil)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                              forKey:iRateRatedVersionKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self synchronizeWhenSafeToDoSo];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (BOOL)ratedAnyVersion {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [(NSString *)[[NSUserDefaults standardUserDefaults] objectForKey:iRateRatedVersionKey] length] != 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)dealloc {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [[NSNotificationCenter defaultCenter] removeObserver:self];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)preventPromptAtNextTest {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    self.shouldPreventPromptAtNextTest = YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)incrementUseCount {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    self.usesCount++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)incrementEventCount {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    self.eventCount++;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (BOOL)shouldPromptForRating {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // Avoid potentially inconvenient prompt
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (self.shouldPreventPromptAtNextTest)
 | 
						
						
						
						
							 | 
							
								 | 
							
							    {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSLog(@"iRate did not prompt for rating because it is potentially inconvenient");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.shouldPreventPromptAtNextTest = NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // preview mode?
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (self.previewMode) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSLog(@"iRate preview mode is enabled - make sure you disable this for release");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // check if we've rated this version
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else if (self.ratedThisVersion) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSLog(@"iRate did not prompt for rating because the user has already rated this version");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // check if we've rated any version
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else if (self.ratedAnyVersion && !self.promptForNewVersionIfUserRated) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSLog(@"iRate did not prompt for rating because the user has already rated this app, and "
 | 
						
						
						
						
							 | 
							
								 | 
							
							                  @"promptForNewVersionIfUserRated is disabled");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // check if we've declined to rate the app
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else if (self.declinedAnyVersion) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSLog(@"iRate did not prompt for rating because the user has declined to rate the app");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // check how long we've been using this version
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else if ([[NSDate date] timeIntervalSinceDate:self.firstUsed] < self.daysUntilPrompt * SECONDS_IN_A_DAY) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSLog(@"iRate did not prompt for rating because the app was first used less than %g days ago",
 | 
						
						
						
						
							 | 
							
								 | 
							
							                  self.daysUntilPrompt);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // check how many times we've used it and the number of significant events
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else if (self.usesCount < self.usesUntilPrompt && self.eventCount < self.eventsUntilPrompt) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSLog(@"iRate did not prompt for rating because the app has only been used %@ times and only %@ events "
 | 
						
						
						
						
							 | 
							
								 | 
							
							                  @"have been logged",
 | 
						
						
						
						
							 | 
							
								 | 
							
							                  @(self.usesCount),
 | 
						
						
						
						
							 | 
							
								 | 
							
							                  @(self.eventCount));
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // check if usage frequency is high enough
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else if (self.usesPerWeek < self.usesPerWeekForPrompt) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSLog(@"iRate did not prompt for rating because the app has only been used %g times per week on average "
 | 
						
						
						
						
							 | 
							
								 | 
							
							                  @"since it was installed",
 | 
						
						
						
						
							 | 
							
								 | 
							
							                  self.usesPerWeek);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // check if within the reminder period
 | 
						
						
						
						
							 | 
							
								 | 
							
							    else if (self.lastReminded != nil &&
 | 
						
						
						
						
							 | 
							
								 | 
							
							             [[NSDate date] timeIntervalSinceDate:self.lastReminded] < self.remindPeriod * SECONDS_IN_A_DAY) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSLog(@"iRate did not prompt for rating because the user last asked to be reminded less than %g days ago",
 | 
						
						
						
						
							 | 
							
								 | 
							
							                  self.remindPeriod);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // lets prompt!
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (NSString *)valueForKey:(NSString *)key inJSON:(id)json {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if ([json isKindOfClass:[NSString class]]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // use legacy parser
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSRange keyRange = [json rangeOfString:[NSString stringWithFormat:@"\"%@\"", key]];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (keyRange.location != NSNotFound) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSInteger start    = keyRange.location + keyRange.length;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSRange valueStart = [json rangeOfString:@":"
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                             options:(NSStringCompareOptions)0
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                               range:NSMakeRange(start, [(NSString *)json length] - start)];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (valueStart.location != NSNotFound) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                start            = valueStart.location + 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                NSRange valueEnd = [json rangeOfString:@","
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                               options:(NSStringCompareOptions)0
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                 range:NSMakeRange(start, [(NSString *)json length] - start)];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (valueEnd.location != NSNotFound) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    NSString *value = [json substringWithRange:NSMakeRange(start, valueEnd.location - start)];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    value = [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    while ([value hasPrefix:@"\""] && ![value hasSuffix:@"\""]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        if (valueEnd.location == NSNotFound) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            break;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        NSInteger newStart = valueEnd.location + 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        valueEnd           = [json rangeOfString:@","
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                               options:(NSStringCompareOptions)0
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                 range:NSMakeRange(newStart, [(NSString *)json length] - newStart)];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        value = [json substringWithRange:NSMakeRange(start, valueEnd.location - start)];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        value =
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    value = [value
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\""]];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    value = [value stringByReplacingOccurrencesOfString:@"\\\\" withString:@"\\"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    value = [value stringByReplacingOccurrencesOfString:@"\\/" withString:@"/"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    value = [value stringByReplacingOccurrencesOfString:@"\\\"" withString:@"\""];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    value = [value stringByReplacingOccurrencesOfString:@"\\n" withString:@"\n"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    value = [value stringByReplacingOccurrencesOfString:@"\\r" withString:@"\r"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    value = [value stringByReplacingOccurrencesOfString:@"\\t" withString:@"\t"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    value = [value stringByReplacingOccurrencesOfString:@"\\f" withString:@"\f"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    value = [value stringByReplacingOccurrencesOfString:@"\\b" withString:@"\f"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    while (YES) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        NSRange unicode = [value rangeOfString:@"\\u"];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        if (unicode.location == NSNotFound || unicode.location + unicode.length == 0) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            break;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        uint32_t c         = 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        NSString *hex      = [value substringWithRange:NSMakeRange(unicode.location + 2, 4)];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        NSScanner *scanner = [NSScanner scannerWithString:hex];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        [scanner scanHexInt:&c];
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        if (c <= 0xffff) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            value = [value
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                stringByReplacingCharactersInRange:NSMakeRange(unicode.location, 6)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                        withString:[NSString stringWithFormat:@"%C", (unichar)c]];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        } else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            // convert character to surrogate pair
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            uint16_t x   = (uint16_t)c;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            uint16_t u   = (c >> 16) & ((1 << 5) - 1);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            uint16_t w   = (uint16_t)u - 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            unichar high = 0xd800 | (w << 6) | x >> 10;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            unichar low  = (uint16_t)(0xdc00 | (x & ((1 << 10) - 1)));
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            value = [value
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                stringByReplacingCharactersInRange:NSMakeRange(unicode.location, 6)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                        withString:[NSString stringWithFormat:@"%C%C", high, low]];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    return value;
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    } else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return json[key];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return nil;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)setAppStoreIDOnMainThread:(NSString *)appStoreIDString {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    _appStoreID = [appStoreIDString integerValue];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [[NSUserDefaults standardUserDefaults] setInteger:_appStoreID forKey:iRateAppStoreIDKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self synchronizeWhenSafeToDoSo];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)connectionSucceeded {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (self.checkingForAppStoreID) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // no longer checking
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.checkingForPrompt     = NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.checkingForAppStoreID = NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // open app store
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self openRatingsPageInAppStore];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    } else if (self.checkingForPrompt) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // no longer checking
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.checkingForPrompt = NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // confirm with delegate
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (![self.delegate iRateShouldPromptForRating]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                NSLog(@"iRate did not display the rating prompt because the iRateShouldPromptForRating delegate method "
 | 
						
						
						
						
							 | 
							
								 | 
							
							                      @"returned NO");
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // prompt user
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self promptForRating];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)connectionError:(NSError *)error {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (self.checkingForPrompt || self.checkingForAppStoreID) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // no longer checking
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.checkingForPrompt     = NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.checkingForAppStoreID = NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // log the error
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (error) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSLog(@"iRate rating process failed because: %@", [error localizedDescription]);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        } else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSLog(@"iRate rating process failed because an unknown error occured");
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // could not connect
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self.delegate iRateCouldNotConnectToAppStore:error];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [[NSNotificationCenter defaultCenter] postNotificationName:iRateCouldNotConnectToAppStore object:error];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)checkForConnectivityInBackground {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if ([NSThread isMainThread]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self performSelectorInBackground:@selector(checkForConnectivityInBackground) withObject:nil];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    @autoreleasepool {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // prevent concurrent checks
 | 
						
						
						
						
							 | 
							
								 | 
							
							        static BOOL checking = NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (checking)
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        checking = YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // first check iTunes
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSString *iTunesServiceURL = [NSString stringWithFormat:iRateAppLookupURLFormat, self.appStoreCountry];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (_appStoreID) // important that we check ivar and not getter in case it has changed
 | 
						
						
						
						
							 | 
							
								 | 
							
							        {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            iTunesServiceURL = [iTunesServiceURL stringByAppendingFormat:@"?id=%@", @(_appStoreID)];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        } else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            iTunesServiceURL = [iTunesServiceURL stringByAppendingFormat:@"?bundleId=%@", self.applicationBundleID];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSLog(@"iRate is checking %@ to retrieve the App Store details...", iTunesServiceURL);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSError *error          = nil;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSURLResponse *response = nil;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSURLRequest *request   = [NSURLRequest requestWithURL:[NSURL URLWithString:iTunesServiceURL]
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                 cachePolicy:NSURLRequestUseProtocolCachePolicy
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                             timeoutInterval:REQUEST_TIMEOUT];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSInteger statusCode = ((NSHTTPURLResponse *)response).statusCode;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (data && statusCode == 200) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // in case error is garbage...
 | 
						
						
						
						
							 | 
							
								 | 
							
							            error = nil;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            id json = nil;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if ([NSJSONSerialization class]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                json = [[NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingOptions)0
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                          error:&error][@"results"] lastObject];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            } else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // convert to string
 | 
						
						
						
						
							 | 
							
								 | 
							
							                json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if (!error) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                NSLog(@"JSON: %@", json);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                // check bundle ID matches
 | 
						
						
						
						
							 | 
							
								 | 
							
							                NSString *bundleID = [self valueForKey:@"bundleId" inJSON:json];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                if (bundleID) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if ([bundleID isEqualToString:self.applicationBundleID]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        // get genre
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        if (self.appStoreGenreID == 0) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            self.appStoreGenreID = [[self valueForKey:@"primaryGenreId" inJSON:json] integerValue];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        // get app id
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        if (!_appStoreID) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            NSString *appStoreIDString = [self valueForKey:@"trackId" inJSON:json];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            [self performSelectorOnMainThread:@selector(setAppStoreIDOnMainThread:)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                   withObject:appStoreIDString
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                waitUntilDone:YES];
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                NSLog(@"iRate found the app on iTunes. The App Store ID is %@", appStoreIDString);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        // check version
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        if (self.onlyPromptIfLatestVersion && !self.previewMode) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            NSString *latestVersion = [self valueForKey:@"version" inJSON:json];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            if ([latestVersion compare:self.applicationVersion options:NSNumericSearch] ==
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                NSOrderedDescending) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                    NSLog(@"iRate found that the installed application version (%@) is not the latest "
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                          @"version on the App Store, which is %@",
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                          self.applicationVersion,
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                          latestVersion);
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                error = [NSError errorWithDomain:iRateErrorDomain
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                            code:iRateErrorApplicationIsNotLatestVersion
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                        userInfo:@{
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                            NSLocalizedDescriptionKey :
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                                @"Installed app is not the latest version available"
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                        }];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    } else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            NSLog(@"iRate found that the application bundle ID (%@) does not match the bundle ID of "
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                  @"the app found on iTunes (%@) with the specified App Store ID (%@)",
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                  self.applicationBundleID,
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                  bundleID,
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                  @(self.appStoreID));
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        error = [NSError
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            errorWithDomain:iRateErrorDomain
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                       code:iRateErrorBundleIdDoesNotMatchAppStore
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                   userInfo:@{
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                       NSLocalizedDescriptionKey : [NSString
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                           stringWithFormat:
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                               @"Application bundle ID does not match expected value of %@", bundleID]
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                   }];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                } else if (_appStoreID || !self.ratingsURL) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        NSLog(@"iRate could not find this application on iTunes. If your app is not intended for App "
 | 
						
						
						
						
							 | 
							
								 | 
							
							                              @"Store release then you must specify a custom ratingsURL. If this is the first release "
 | 
						
						
						
						
							 | 
							
								 | 
							
							                              @"of your application then it's not a problem that it cannot be found on the store yet");
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    if (!self.previewMode) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                        error = [NSError errorWithDomain:iRateErrorDomain
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                    code:iRateErrorApplicationNotFoundOnAppStore
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                userInfo:@{
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                    NSLocalizedDescriptionKey :
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                        @"The application could not be found on the App Store."
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                }];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							                } else if (!_appStoreID && self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                    NSLog(@"iRate could not find your app on iTunes. If your app is not yet on the store or is not "
 | 
						
						
						
						
							 | 
							
								 | 
							
							                          @"intended for App Store release then don't worry about this");
 | 
						
						
						
						
							 | 
							
								 | 
							
							                }
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        } else if (statusCode >= 400) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // http error
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSString *message = [NSString stringWithFormat:@"The server returned a %@ error", @(statusCode)];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            error             = [NSError errorWithDomain:@"HTTPResponseErrorDomain"
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                        code:statusCode
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                    userInfo:@{NSLocalizedDescriptionKey : message}];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // handle errors (ignoring sandbox issues)
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (error && !(error.code == EPERM && [error.domain isEqualToString:NSPOSIXErrorDomain] && _appStoreID)) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [self performSelectorOnMainThread:@selector(connectionError:) withObject:error waitUntilDone:YES];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        } else if (self.appStoreID || self.previewMode) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // show prompt
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [self performSelectorOnMainThread:@selector(connectionSucceeded) withObject:nil waitUntilDone:YES];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // finished
 | 
						
						
						
						
							 | 
							
								 | 
							
							        checking = NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)promptIfNetworkAvailable {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (!self.checkingForPrompt && !self.checkingForAppStoreID) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.checkingForPrompt = YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self checkForConnectivityInBackground];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (BOOL)promptIfAllCriteriaMet {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if ([self shouldPromptForRating]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self promptIfNetworkAvailable];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (BOOL)showRemindButton {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [self.remindButtonLabel length];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (BOOL)showCancelButton {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    return [self.cancelButtonLabel length];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)promptForRating {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (!self.visibleAlert) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSString *message = self.ratedAnyVersion ? self.updateMessage : self.message;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#if TARGET_OS_IPHONE
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        UIViewController *topController = [UIApplication sharedApplication].delegate.window.rootViewController;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        while (topController.presentedViewController) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            topController = topController.presentedViewController;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if ([UIAlertController class] && topController && self.useUIAlertControllerIfAvailable) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            UIAlertController *alert = [UIAlertController alertControllerWithTitle:self.messageTitle
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                                           message:message
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                                    preferredStyle:UIAlertControllerStyleAlert];
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // rate action
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [alert addAction:[UIAlertAction actionWithTitle:self.rateButtonLabel
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                      style:UIAlertActionStyleDefault
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                    handler:^(__unused UIAlertAction *action) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                      [self didDismissAlert:alert withButtonAtIndex:0];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                    }]];
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // cancel action
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if ([self showCancelButton]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                [alert addAction:[UIAlertAction actionWithTitle:self.cancelButtonLabel
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                          style:UIAlertActionStyleCancel
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                        handler:^(__unused UIAlertAction *action) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                          [self didDismissAlert:alert withButtonAtIndex:1];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                        }]];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // remind action
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if ([self showRemindButton]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                [alert addAction:[UIAlertAction actionWithTitle:self.remindButtonLabel
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                          style:UIAlertActionStyleDefault
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                        handler:^(__unused UIAlertAction *action) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                          [self didDismissAlert:alert
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                              withButtonAtIndex:[self showCancelButton] ? 2 : 1];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                        }]];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            self.visibleAlert = alert;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // get current view controller and present alert
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [topController presentViewController:alert animated:YES completion:NULL];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        } else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:self.messageTitle
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                            message:message
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                           delegate:(id<UIAlertViewDelegate>)self
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                  cancelButtonTitle:nil
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                  otherButtonTitles:self.rateButtonLabel, nil];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if ([self showCancelButton]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                [alert addButtonWithTitle:self.cancelButtonLabel];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                alert.cancelButtonIndex = 1;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            if ([self showRemindButton]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                [alert addButtonWithTitle:self.remindButtonLabel];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							            self.visibleAlert = alert;
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [self.visibleAlert show];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#else
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // only show when main window is available
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (self.onlyPromptIfMainWindowIsAvailable && ![[NSApplication sharedApplication] mainWindow]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [self performSelector:@selector(promptForRating) withObject:nil afterDelay:0.5];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSAlert *alert        = [[NSAlert alloc] init];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        alert.messageText     = self.messageTitle;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        alert.informativeText = message;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [alert addButtonWithTitle:self.rateButtonLabel];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if ([self showCancelButton]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [alert addButtonWithTitle:self.cancelButtonLabel];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if ([self showRemindButton]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [alert addButtonWithTitle:self.remindButtonLabel];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.visibleAlert = alert;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (![alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [alert beginSheetModalForWindow:[NSApplication sharedApplication].mainWindow
 | 
						
						
						
						
							 | 
							
								 | 
							
							                              modalDelegate:self
 | 
						
						
						
						
							 | 
							
								 | 
							
							                             didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                contextInfo:nil];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        } else
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#endif
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [alert beginSheetModalForWindow:[NSApplication sharedApplication].mainWindow
 | 
						
						
						
						
							 | 
							
								 | 
							
							                          completionHandler:^(NSModalResponse returnCode) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							                            [self didDismissAlert:alert withButtonAtIndex:returnCode - NSAlertFirstButtonReturn];
 | 
						
						
						
						
							 | 
							
								 | 
							
							                          }];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#endif
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // inform about prompt
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self.delegate iRateDidPromptForRating];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [[NSNotificationCenter defaultCenter] postNotificationName:iRateDidPromptForRating object:nil];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)applicationLaunched {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // check if this is a new version
 | 
						
						
						
						
							 | 
							
								 | 
							
							    NSUserDefaults *defaults  = [NSUserDefaults standardUserDefaults];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    NSString *lastUsedVersion = [defaults objectForKey:iRateLastVersionUsedKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (!self.firstUsed || ![lastUsedVersion isEqualToString:self.applicationVersion]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [defaults setObject:self.applicationVersion forKey:iRateLastVersionUsedKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!self.firstUsed || [self ratedAnyVersion]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // reset defaults
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [defaults setObject:[NSDate date] forKey:iRateFirstUsedKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [defaults setInteger:0 forKey:iRateUseCountKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [defaults setInteger:0 forKey:iRateEventCountKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [defaults setObject:nil forKey:iRateLastRemindedKey];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [self synchronizeWhenSafeToDoSo];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        } else if ([[NSDate date] timeIntervalSinceDate:self.firstUsed] >
 | 
						
						
						
						
							 | 
							
								 | 
							
							                   (self.daysUntilPrompt - 1) * SECONDS_IN_A_DAY) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // if was previously installed, but we haven't yet prompted for a rating
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // don't reset, but make sure it won't rate for a day at least
 | 
						
						
						
						
							 | 
							
								 | 
							
							            self.firstUsed = [[NSDate date] dateByAddingTimeInterval:(self.daysUntilPrompt - 1) * -SECONDS_IN_A_DAY];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // inform about app update
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self.delegate iRateDidDetectAppUpdate];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [[NSNotificationCenter defaultCenter] postNotificationName:iRateDidDetectAppUpdate object:nil];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self incrementUseCount];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (self.shouldPromptForRating) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self promptForRating];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)didDismissAlert:(__unused id)alertView withButtonAtIndex:(NSInteger)buttonIndex {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // get button indices
 | 
						
						
						
						
							 | 
							
								 | 
							
							    NSInteger rateButtonIndex   = 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    NSInteger cancelButtonIndex = [self showCancelButton] ? 1 : 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    NSInteger remindButtonIndex = [self showRemindButton] ? cancelButtonIndex + 1 : 0;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (buttonIndex == rateButtonIndex) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self rate];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    } else if (buttonIndex == cancelButtonIndex) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self declineThisVersion];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    } else if (buttonIndex == remindButtonIndex) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self remindLater];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // release alert
 | 
						
						
						
						
							 | 
							
								 | 
							
							    self.visibleAlert = nil;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#if TARGET_OS_IPHONE
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)applicationWillEnterForeground {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self incrementUseCount];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							// Only synchronize when active.
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)synchronizeWhenSafeToDoSo
 | 
						
						
						
						
							 | 
							
								 | 
							
							{
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.hasQueuedSynchronize = YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [[NSUserDefaults standardUserDefaults] synchronize];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    self.hasQueuedSynchronize = NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							// Only synchronize when active.
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)applicationDidBecomeActive
 | 
						
						
						
						
							 | 
							
								 | 
							
							{
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (self.hasQueuedSynchronize) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [[NSUserDefaults standardUserDefaults] synchronize];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.hasQueuedSynchronize = NO;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (self.promptAtLaunch && !self.hasPromptedAtLaunch) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if ([self promptIfAllCriteriaMet]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            self.hasPromptedAtLaunch = YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)openRatingsPageInAppStore {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (!_ratingsURL && !self.appStoreID) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.checkingForAppStoreID = YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!self.checkingForPrompt) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [self checkForConnectivityInBackground];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    NSString *cantOpenMessage = nil;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#if TARGET_IPHONE_SIMULATOR
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if ([[self.ratingsURL scheme] isEqualToString:iRateiOSAppStoreURLScheme]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        cantOpenMessage =
 | 
						
						
						
						
							 | 
							
								 | 
							
							            @"iRate could not open the ratings page because the App Store is not available on the iOS simulator";
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#elif DEBUG
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (![[UIApplication sharedApplication] canOpenURL:self.ratingsURL]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        cantOpenMessage =
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [NSString stringWithFormat:@"iRate was unable to open the specified ratings URL: %@", self.ratingsURL];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#endif
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (cantOpenMessage) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSLog(@"%@", cantOpenMessage);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSError *error = [NSError errorWithDomain:iRateErrorDomain
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                             code:iRateErrorCouldNotOpenRatingPageURL
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                         userInfo:@{NSLocalizedDescriptionKey : cantOpenMessage}];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self.delegate iRateCouldNotConnectToAppStore:error];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [[NSNotificationCenter defaultCenter] postNotificationName:iRateCouldNotConnectToAppStore object:error];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    } else {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            NSLog(@"iRate will open the App Store ratings page using the following URL: %@", self.ratingsURL);
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [[UIApplication sharedApplication] openURL:self.ratingsURL];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self.delegate iRateDidOpenAppStore];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [[NSNotificationCenter defaultCenter] postNotificationName:iRateDidOpenAppStore object:nil];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self didDismissAlert:alertView withButtonAtIndex:buttonIndex];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#else
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)openAppPageWhenAppStoreLaunched {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // check if app store is running
 | 
						
						
						
						
							 | 
							
								 | 
							
							    for (NSRunningApplication *app in [[NSWorkspace sharedWorkspace] runningApplications]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if ([app.bundleIdentifier isEqualToString:iRateMacAppStoreBundleID]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            // open app page
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [[NSWorkspace sharedWorkspace] performSelector:@selector(openURL:)
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                withObject:self.ratingsURL
 | 
						
						
						
						
							 | 
							
								 | 
							
							                                                afterDelay:MAC_APP_STORE_REFRESH_DELAY];
 | 
						
						
						
						
							 | 
							
								 | 
							
							            return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // try again
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self performSelector:@selector(openAppPageWhenAppStoreLaunched) withObject:nil afterDelay:0.0];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)openRatingsPageInAppStore {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (!_ratingsURL && !self.appStoreID) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        self.checkingForAppStoreID = YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							        if (!self.checkingForPrompt) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							            [self checkForConnectivityInBackground];
 | 
						
						
						
						
							 | 
							
								 | 
							
							        }
 | 
						
						
						
						
							 | 
							
								 | 
							
							        return;
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (self.verboseLogging) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        NSLog(@"iRate will open the App Store ratings page using the following URL: %@", self.ratingsURL);
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [[NSWorkspace sharedWorkspace] openURL:self.ratingsURL];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self openAppPageWhenAppStoreLaunched];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self.delegate iRateDidOpenAppStore];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(__unused void *)contextInfo {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self didDismissAlert:alert withButtonAtIndex:returnCode - NSAlertFirstButtonReturn];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#endif
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)logEvent:(BOOL)deferPrompt {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self incrementEventCount];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if (!deferPrompt) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self promptIfAllCriteriaMet];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							#pragma mark - User's actions
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)declineThisVersion {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // ignore this version
 | 
						
						
						
						
							 | 
							
								 | 
							
							    self.declinedThisVersion = YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // log event
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self.delegate iRateUserDidDeclineToRateApp];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [[NSNotificationCenter defaultCenter] postNotificationName:iRateUserDidDeclineToRateApp object:nil];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)remindLater {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // remind later
 | 
						
						
						
						
							 | 
							
								 | 
							
							    self.lastReminded = [NSDate date];
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // log event
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self.delegate iRateUserDidRequestReminderToRateApp];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [[NSNotificationCenter defaultCenter] postNotificationName:iRateUserDidRequestReminderToRateApp object:nil];
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							- (void)rate {
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // mark as rated
 | 
						
						
						
						
							 | 
							
								 | 
							
							    self.ratedThisVersion = YES;
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    // log event
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [self.delegate iRateUserDidAttemptToRateApp];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    [[NSNotificationCenter defaultCenter] postNotificationName:iRateUserDidAttemptToRateApp object:nil];
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							    if ([self.delegate iRateShouldOpenAppStore]) {
 | 
						
						
						
						
							 | 
							
								 | 
							
							        // launch mac app store
 | 
						
						
						
						
							 | 
							
								 | 
							
							        [self openRatingsPageInAppStore];
 | 
						
						
						
						
							 | 
							
								 | 
							
							    }
 | 
						
						
						
						
							 | 
							
								 | 
							
							}
 | 
						
						
						
						
							 | 
							
								 | 
							
							
 | 
						
						
						
						
							 | 
							
								 | 
							
							@end
 |