From 0495a34c6aff53ab6935475bd0e26c5199447c2a Mon Sep 17 00:00:00 2001 From: Jon Date: Mon, 14 Dec 2015 09:21:55 -0500 Subject: [PATCH 01/16] Move increment methods to a private serial queue to guarantee proper incrementing --- Appirater.m | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Appirater.m b/Appirater.m index 951b8920..095bf34d 100644 --- a/Appirater.m +++ b/Appirater.m @@ -76,6 +76,7 @@ @interface Appirater () @property (nonatomic, copy) NSString *alertCancelTitle; @property (nonatomic, copy) NSString *alertRateTitle; @property (nonatomic, copy) NSString *alertRateLaterTitle; +@property (nonatomic, strong) NSOperationQueue *eventQueue; - (BOOL)connectedToNetwork; + (Appirater*)sharedInstance; - (void)showPromptWithChecks:(BOOL)withChecks @@ -260,6 +261,8 @@ + (Appirater*)sharedInstance { dispatch_once(&onceToken, ^{ appirater = [[Appirater alloc] init]; appirater.delegate = _delegate; + appirater.eventQueue = [[NSOperationQueue alloc] init]; + appirater.eventQueue.maxConcurrentOperationCount = 1; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive) name: UIApplicationWillResignActiveNotification object:nil]; }); @@ -535,17 +538,17 @@ + (void)appWillResignActive { } + (void)appEnteredForeground:(BOOL)canPromptForRating { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), - ^{ - [[Appirater sharedInstance] incrementAndRate:canPromptForRating]; - }); + Appirater *a = [Appirater sharedInstance]; + [a.eventQueue addOperationWithBlock:^{ + [[Appirater sharedInstance] incrementAndRate:canPromptForRating]; + }]; } + (void)userDidSignificantEvent:(BOOL)canPromptForRating { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), - ^{ - [[Appirater sharedInstance] incrementSignificantEventAndRate:canPromptForRating]; - }); + Appirater *a = [Appirater sharedInstance]; + [a.eventQueue addOperationWithBlock:^{ + [[Appirater sharedInstance] incrementSignificantEventAndRate:canPromptForRating]; + }]; } #pragma GCC diagnostic push From b9b2b4501fdb5bb36040b3afb2bc6bb8d8ae3b2a Mon Sep 17 00:00:00 2001 From: ReadmeCritic Date: Wed, 10 Feb 2016 15:10:16 -0800 Subject: [PATCH 02/16] Correct the spelling of CocoaPods in README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0278daa0..e826e1fc 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ the library check out the [Appirater group] [appiratergroup]. Getting Started --------------- -###Cocoapods -If you're new to Cocoapods [watch this](http://nsscreencast.com/episodes/5-cocoapods). To add Appirater to your app, add `pod "Appirater"` to your Podfile. +###CocoaPods +If you're new to CocoaPods [watch this](http://nsscreencast.com/episodes/5-cocoapods). To add Appirater to your app, add `pod "Appirater"` to your Podfile. -Cocoapods support is still experimental, and might not work in all use cases. If you experience problems, open an issue and install via Git submodule +CocoaPods support is still experimental, and might not work in all use cases. If you experience problems, open an issue and install via Git submodule ###Manually 1. Add the Appirater code into your project. From 7dc2fb541fcf769faa7f4a1a281617afd08f0980 Mon Sep 17 00:00:00 2001 From: Leandro Lopez Date: Thu, 3 Nov 2016 14:01:11 -0300 Subject: [PATCH 03/16] Replacing NSURLConnection with NSURLSession. --- Appirater.m | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Appirater.m b/Appirater.m index 951b8920..8dbadabc 100644 --- a/Appirater.m +++ b/Appirater.m @@ -246,10 +246,17 @@ - (BOOL)connectedToNetwork { BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection; NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"]; - NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0]; - NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:self]; - return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO; + NSURLSessionConfiguration* sessionConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + sessionConfiguration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData; + sessionConfiguration.timeoutIntervalForRequest = 20.0; + + NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration]; + + NSURLSessionTask *task = [session dataTaskWithURL:testURL]; + [task resume]; + + return ((isReachable && !needsConnection) || nonWiFi) ? ( (task.state != NSURLSessionTaskStateSuspended) ? YES : NO ) : NO; } + (Appirater*)sharedInstance { From ce6ece738fa941b29cca06b5db21fca6d0d0d5a4 Mon Sep 17 00:00:00 2001 From: Arash Payan Date: Fri, 4 Nov 2016 06:20:49 -0700 Subject: [PATCH 04/16] Suppress deprecation warnings related to UIAlertView and calls to set status bar style when using StoreKit (nobody should be using StoreKit anyway) --- Appirater.m | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Appirater.m b/Appirater.m index 0cf28b77..10fac29c 100644 --- a/Appirater.m +++ b/Appirater.m @@ -645,11 +645,6 @@ + (void)rateApp { } [[self getRootViewController] presentViewController:storeViewController animated:_usesAnimation completion:^{ [self setModalOpen:YES]; - //Temporarily use a black status bar to match the StoreKit view. - [self setStatusBarStyle:[UIApplication sharedApplication].statusBarStyle]; -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 - [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent animated:_usesAnimation]; -#endif }]; //Use the standard openUrl method if StoreKit is unavailable. @@ -722,7 +717,6 @@ - (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewContr //Close the in-app rating (StoreKit) view and restore the previous status bar style. + (void)closeModal { if (_modalOpen) { - [[UIApplication sharedApplication]setStatusBarStyle:_statusBarStyle animated:_usesAnimation]; BOOL usedAnimation = _usesAnimation; [self setModalOpen:NO]; From 9393b3b103123e5f0b46c8c3a3f1c395df4ffa50 Mon Sep 17 00:00:00 2001 From: Arash Payan Date: Fri, 4 Nov 2016 06:27:47 -0700 Subject: [PATCH 05/16] Use @import instead #import. Now really include the warning suppression code. --- Appirater.h | 11 ++++++++--- Appirater.m | 3 ++- AppiraterDelegate.h | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Appirater.h b/Appirater.h index 2263a0b9..928d9096 100644 --- a/Appirater.h +++ b/Appirater.h @@ -34,9 +34,9 @@ * Copyright 2012 Arash Payan. All rights reserved. */ -#import +@import Foundation; +@import StoreKit; #import "AppiraterDelegate.h" -#import extern NSString *const kAppiraterFirstUseDate; extern NSString *const kAppiraterUseCount; @@ -86,11 +86,16 @@ extern NSString *const kAppiraterReminderRequestDate; #define APPIRATER_RATE_LATER NSLocalizedStringFromTableInBundle(@"Remind me later", @"AppiraterLocalizable", [Appirater bundle], nil) @interface Appirater : NSObject { - +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" UIAlertView *ratingAlert; +#pragma clang diagnostic pop } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" @property(nonatomic, strong) UIAlertView *ratingAlert; +#pragma clan diagnostic pop @property(nonatomic) BOOL openInAppStore; #if __has_feature(objc_arc_weak) @property(nonatomic, weak) NSObject *delegate; diff --git a/Appirater.m b/Appirater.m index 10fac29c..9cac825f 100644 --- a/Appirater.m +++ b/Appirater.m @@ -34,8 +34,9 @@ * Copyright 2012 Arash Payan. All rights reserved. */ +@import SystemConfiguration; +@import CFNetwork; #import "Appirater.h" -#import #include #if ! __has_feature(objc_arc) diff --git a/AppiraterDelegate.h b/AppiraterDelegate.h index cbe0cfad..114a6b61 100644 --- a/AppiraterDelegate.h +++ b/AppiraterDelegate.h @@ -6,7 +6,7 @@ // Copyright (c) 2012 News.me. All rights reserved. // -#import +@import Foundation; @class Appirater; From 29cee6a04e33d6a5523051595e636052a72d52ce Mon Sep 17 00:00:00 2001 From: Arash Payan Date: Fri, 4 Nov 2016 06:46:41 -0700 Subject: [PATCH 06/16] Update CHANGELOG and README for 2.1.0 release. --- CHANGELOG.md | 6 ++++++ README.md | 26 +++++++++----------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd87b632..4a70fd5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ Change Log ========== +Version 2.1.0 *(2016-11-04)* +---------------------------- +* Fix and suppress various Xcode warnings +* Switch to NSURLSession +* Serialize incrementing events + Version 2.0.4 *(2014-09-18)* ---------------------------- * Change: Better URL for iOS 7.1 and 8 support diff --git a/README.md b/README.md index e826e1fc..0db2443e 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,15 @@ Introduction ------------- +--------------- + Appirater is a class that you can drop into any iPhone app (iOS 4.0 or later) that will help remind your users to review your app on the App Store. The code is released under the MIT/X11, so feel free to -modify and share your changes with the world. Read on below for how to get started. If you need any help using, -the library check out the [Appirater group] [appiratergroup]. - +modify and share your changes with the world. Read on below for how to get started. If you need any help using, the library, post your questions on [Stack Overflow] [stackoverflow] under the `appirater` tag. Getting Started --------------- -###CocoaPods -If you're new to CocoaPods [watch this](http://nsscreencast.com/episodes/5-cocoapods). To add Appirater to your app, add `pod "Appirater"` to your Podfile. - -CocoaPods support is still experimental, and might not work in all use cases. If you experience problems, open an issue and install via Git submodule - -###Manually -1. Add the Appirater code into your project. -2. If your project doesn't use ARC, add the `-fobjc-arc` compiler flag to `Appirater.m` in your target's Build Phases » Compile Sources section. -3. Add the `CFNetwork`, `SystemConfiguration`, and `StoreKit` frameworks to your project. Be sure to **change Required to Optional** for StoreKit in your target's Build Phases » Link Binary with Libraries section. +### CocoaPods +To add Appirater to your app, add `pod "Appirater"` to your Podfile. Configuration ------------- @@ -73,7 +65,7 @@ Requests for help, questions about usage, suggestions and other relevant topics License ------- -Copyright 2014. [Arash Payan] [arash]. +Copyright 2016. [Arash Payan] [arash]. This library is distributed under the terms of the MIT/X11. While not required, I greatly encourage and appreciate any improvements that you make @@ -88,9 +80,9 @@ A few people have ported Appirater to other SDKs. The ports are listed here in h + Corona SDK. [Github] [coronasdkport] + Titanium SDK. [Github] [titaniumport] -[appiratergroup]: http://groups.google.com/group/appirater -[homepage]: http://arashpayan.com/blog/index.php/2009/09/07/presenting-appirater/ -[arash]: http://arashpayan.com +[stackoverflow]: http://stackoverflow.com/ +[homepage]: https://arashpayan.com/blog/2009/09/07/presenting-appirater/ +[arash]: https://arashpayan.com [Appirater.h]: https://github.com/arashpayan/appirater/blob/master/Appirater.h [monotouchport]: https://github.com/chebum/Appirater-for-MonoTouch [monotouchbinding]: https://github.com/theonlylawislove/MonoTouch.Appirater From c07c7769e59c3e0fe9c0ef26e750d4cdde884632 Mon Sep 17 00:00:00 2001 From: Arash Payan Date: Fri, 4 Nov 2016 06:58:26 -0700 Subject: [PATCH 07/16] Updated podspec to 2.1.0 --- Appirater.podspec.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Appirater.podspec.json b/Appirater.podspec.json index 74f2903d..b0db7193 100644 --- a/Appirater.podspec.json +++ b/Appirater.podspec.json @@ -1,17 +1,17 @@ { "name": "Appirater", - "version": "2.0.5", + "version": "2.1.0", "platforms": { "ios": "5.0" }, "summary": "A utility that reminds your iPhone app's users to review the app.", - "homepage": "http://arashpayan.com/blog/2009/09/07/presenting-appirater/", + "homepage": "https://arashpayan.com/blog/2009/09/07/presenting-appirater/", "authors": { "Arash Payan": "arash@ara.sh" }, "source": { "git": "https://github.com/arashpayan/appirater.git", - "tag": "2.0.5" + "tag": "2.1.0" }, "source_files": "*.{h,m}", "resource_bundles": { @@ -27,6 +27,6 @@ "weak_frameworks": "StoreKit", "license": { "type": "MIT", - "text": "Copyright 2015. Arash Payan. This library is distributed under the terms of the MIT/X11." + "text": "Copyright 2016. Arash Payan. This library is distributed under the terms of the MIT/X11." } } From 7218e476670ba0c0c965ff8c3868dad02cf36873 Mon Sep 17 00:00:00 2001 From: Alexandre Blin Date: Fri, 4 Nov 2016 15:50:20 +0100 Subject: [PATCH 08/16] Fix typo in #pragma line --- Appirater.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Appirater.h b/Appirater.h index 928d9096..bba1d072 100644 --- a/Appirater.h +++ b/Appirater.h @@ -95,7 +95,7 @@ extern NSString *const kAppiraterReminderRequestDate; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" @property(nonatomic, strong) UIAlertView *ratingAlert; -#pragma clan diagnostic pop +#pragma clang diagnostic pop @property(nonatomic) BOOL openInAppStore; #if __has_feature(objc_arc_weak) @property(nonatomic, weak) NSObject *delegate; From ea37962fc485431dca6ede9eaa64323eb810fdd9 Mon Sep 17 00:00:00 2001 From: Reiner Pittinger Date: Fri, 11 Nov 2016 01:14:46 +0100 Subject: [PATCH 09/16] Use #import instead of @import (#246) Use #import instead of @import --- Appirater.h | 4 ++-- Appirater.m | 4 ++-- AppiraterDelegate.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Appirater.h b/Appirater.h index bba1d072..2ca0fab9 100644 --- a/Appirater.h +++ b/Appirater.h @@ -34,8 +34,8 @@ * Copyright 2012 Arash Payan. All rights reserved. */ -@import Foundation; -@import StoreKit; +#import +#import #import "AppiraterDelegate.h" extern NSString *const kAppiraterFirstUseDate; diff --git a/Appirater.m b/Appirater.m index 9cac825f..de27b26d 100644 --- a/Appirater.m +++ b/Appirater.m @@ -34,8 +34,8 @@ * Copyright 2012 Arash Payan. All rights reserved. */ -@import SystemConfiguration; -@import CFNetwork; +#import +#import #import "Appirater.h" #include diff --git a/AppiraterDelegate.h b/AppiraterDelegate.h index 114a6b61..cbe0cfad 100644 --- a/AppiraterDelegate.h +++ b/AppiraterDelegate.h @@ -6,7 +6,7 @@ // Copyright (c) 2012 News.me. All rights reserved. // -@import Foundation; +#import @class Appirater; From b6f4b712a172c32b97339e2e95c9a08bae94e4a8 Mon Sep 17 00:00:00 2001 From: Farzad Sharbafian Date: Thu, 26 Jan 2017 21:49:42 +0100 Subject: [PATCH 10/16] Add Persian Localizatoin (#249) * Add Persian Localization --- fa.lproj/AppiraterLocalizable.strings | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 fa.lproj/AppiraterLocalizable.strings diff --git a/fa.lproj/AppiraterLocalizable.strings b/fa.lproj/AppiraterLocalizable.strings new file mode 100644 index 00000000..c30a6810 --- /dev/null +++ b/fa.lproj/AppiraterLocalizable.strings @@ -0,0 +1,5 @@ +"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!" = "اگر از استفاده برنامه %@ لذت می‌برید، زمان دارید بهش امتیاز دهید؟ بیشتر از یک دقیقه زمان نخواهد گرفت. با تشکر از اینکه ما را همایت می‌کنید."; +"Rate %@" = "ارزیابی کردن %@"; +"No, Thanks" = "نه، مرسی"; +"Remind me later" = "بعدا"; + From e5b671e7c139b47e12c94fc65493b52483a0bcf7 Mon Sep 17 00:00:00 2001 From: Markus Chmelar Date: Sun, 24 Sep 2017 00:37:14 +0200 Subject: [PATCH 11/16] Use SKStoreReviewController if available (#258) --- Appirater.m | 52 ++++++++++++++++++++++++++++++++++------------------ CHANGELOG.md | 6 ++++++ README.md | 8 ++++++++ 3 files changed, 48 insertions(+), 18 deletions(-) diff --git a/Appirater.m b/Appirater.m index de27b26d..3bb8165b 100644 --- a/Appirater.m +++ b/Appirater.m @@ -280,33 +280,39 @@ + (Appirater*)sharedInstance { } - (void)showRatingAlert:(BOOL)displayRateLaterButton { - UIAlertView *alertView = nil; id delegate = _delegate; if(delegate && [delegate respondsToSelector:@selector(appiraterShouldDisplayAlert:)] && ![delegate appiraterShouldDisplayAlert:self]) { return; } - if (displayRateLaterButton) { - alertView = [[UIAlertView alloc] initWithTitle:self.alertTitle - message:self.alertMessage - delegate:self - cancelButtonTitle:self.alertCancelTitle - otherButtonTitles:self.alertRateTitle, self.alertRateLaterTitle, nil]; + if (NSStringFromClass([SKStoreReviewController class]) != nil) { + // If SKStoreReviewController is used, skip the custom dialog and directly go the the rating + [Appirater rateApp]; } else { - alertView = [[UIAlertView alloc] initWithTitle:self.alertTitle - message:self.alertMessage - delegate:self - cancelButtonTitle:self.alertCancelTitle - otherButtonTitles:self.alertRateTitle, nil]; - } - - self.ratingAlert = alertView; + // Otherwise show a custom Alert + UIAlertView *alertView = nil; + if (displayRateLaterButton) { + alertView = [[UIAlertView alloc] initWithTitle:self.alertTitle + message:self.alertMessage + delegate:self + cancelButtonTitle:self.alertCancelTitle + otherButtonTitles:self.alertRateTitle, self.alertRateLaterTitle, nil]; + } else { + alertView = [[UIAlertView alloc] initWithTitle:self.alertTitle + message:self.alertMessage + delegate:self + cancelButtonTitle:self.alertCancelTitle + otherButtonTitles:self.alertRateTitle, nil]; + } + + self.ratingAlert = alertView; [alertView show]; + } - if (delegate && [delegate respondsToSelector:@selector(appiraterDidDisplayAlert:)]) { - [delegate appiraterDidDisplayAlert:self]; - } + if (delegate && [delegate respondsToSelector:@selector(appiraterDidDisplayAlert:)]) { + [delegate appiraterDidDisplayAlert:self]; + } } - (void)showRatingAlert @@ -628,10 +634,20 @@ + (UIViewController *) topMostViewController: (UIViewController *) controller { + (void)rateApp { + //Use the built SKStoreReviewController if available (available from iOS 10.3 upwards) + if (NSStringFromClass([SKStoreReviewController class]) != nil) { + // Also note, that SKStoreReviewController takes care of impression limitation by itself so it's ok to not save the impression manually + // This also works in the simulator + [SKStoreReviewController requestReview]; + return; + } + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion]; [userDefaults synchronize]; + + //Use the in-app StoreKit view if available (iOS 6) and imported. This works in the simulator. if (![Appirater sharedInstance].openInAppStore && NSStringFromClass([SKStoreProductViewController class]) != nil) { diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a70fd5f..ed64ce60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ Change Log ========== +Unreleased: +---------------------------- +* Use SKStoreReviewController if available + * Available on iOS > 10.3 + * You'll need to link the StoreKit Framework + Version 2.1.0 *(2016-11-04)* ---------------------------- * Fix and suppress various Xcode warnings diff --git a/README.md b/README.md index 0db2443e..3accb178 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,14 @@ If you wanted to show the request after 5 days only you can set the following: [Appirater appLaunched:YES]; ``` +SKStoreReviewController +---------------------- +In iOS 10.3, [SKStoreReviewController](https://developer.apple.com/library/content/releasenotes/General/WhatsNewIniOS/Articles/iOS10_3.html) was introduced which allows rating directly within the app without any additional setup. + +Appirater automatically uses `SKStoreReviewController` if available. You'll need to manually link `StoreKit` in your App however. + +If `SKStoreReviewController` is used, Appirater is used only to decide when to show the rating dialog to the user. Keep in mind, that `SKStoreReviewController` automatically limits the number of impressions, so the dialog might be displayed less frequently than your configured conditions might suggest. + Help and Support Group ---------------------- Requests for help, questions about usage, suggestions and other relevant topics should be posted at the [Appirater group] [appiratergroup]. As much as I'd like to help everyone who emails me, I can't respond to private emails, but I'll respond to posts on the group where others can benefit from the Q&As. From 5107d04b3b1dfcc07efeae6ca45ceedfa683e5ca Mon Sep 17 00:00:00 2001 From: Arash Payan Date: Sat, 23 Sep 2017 15:47:16 -0700 Subject: [PATCH 12/16] Remove unnecessary [NSString stringWithFormat] calls (fixes #220) --- Appirater.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Appirater.m b/Appirater.m index 3bb8165b..f41fedab 100644 --- a/Appirater.m +++ b/Appirater.m @@ -670,17 +670,17 @@ + (void)rateApp { #if TARGET_IPHONE_SIMULATOR NSLog(@"APPIRATER NOTE: iTunes App Store is not supported on the iOS simulator. Unable to open App Store page."); #else - NSString *reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%@", _appId]]; + NSString *reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:_appId]; // iOS 7 needs a different templateReviewURL @see https://github.com/arashpayan/appirater/issues/131 // Fixes condition @see https://github.com/arashpayan/appirater/issues/205 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 && [[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) { - reviewURL = [templateReviewURLiOS7 stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%@", _appId]]; + reviewURL = [templateReviewURLiOS7 stringByReplacingOccurrencesOfString:@"APP_ID" withString:_appId]; } // iOS 8 needs a different templateReviewURL also @see https://github.com/arashpayan/appirater/issues/182 else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) { - reviewURL = [templateReviewURLiOS8 stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%@", _appId]]; + reviewURL = [templateReviewURLiOS8 stringByReplacingOccurrencesOfString:@"APP_ID" withString:_appId]; } [[UIApplication sharedApplication] openURL:[NSURL URLWithString:reviewURL]]; From 6df2a754e54aad79da2672d259445ef832ed0770 Mon Sep 17 00:00:00 2001 From: Arash Payan Date: Sat, 23 Sep 2017 15:52:26 -0700 Subject: [PATCH 13/16] Add Armenian localization (fixes #158) --- hy.lproj/AppiraterLocalizable.strings | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 hy.lproj/AppiraterLocalizable.strings diff --git a/hy.lproj/AppiraterLocalizable.strings b/hy.lproj/AppiraterLocalizable.strings new file mode 100644 index 00000000..8a398194 --- /dev/null +++ b/hy.lproj/AppiraterLocalizable.strings @@ -0,0 +1,4 @@ +"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!" = "Եթե Դուք հաճույքով եք օգտագործում %@-ը, դեմ չե՞ք լինի տրամադրել մեկ րոպե այն գնահատելու համար: Այն չի պահանջի ձեզանից ավելի քան մեկ րոպե: Շնորհակալություն աջակցության համար:"; +"Rate %@" = "Գնահատել %@-ը"; +"No, Thanks" = "Ոչ, շնորհակալություն"; +"Remind me later" = "Հիշեցնել ավելի ուշ"; From 24eb76bf4df29adc7b1879b0ee26751086cefb5b Mon Sep 17 00:00:00 2001 From: Arash Payan Date: Sat, 23 Sep 2017 16:59:42 -0700 Subject: [PATCH 14/16] Fixes #215 (delegate not setting after singleton is instantiated) --- Appirater.m | 8 +------- CHANGELOG.md | 2 ++ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/Appirater.m b/Appirater.m index f41fedab..fa629b87 100644 --- a/Appirater.m +++ b/Appirater.m @@ -61,11 +61,6 @@ static NSInteger _significantEventsUntilPrompt = -1; static double _timeBeforeReminding = 1; static BOOL _debug = NO; -#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 - static id _delegate; -#else - __weak static id _delegate; -#endif static BOOL _usesAnimation = TRUE; static UIStatusBarStyle _statusBarStyle; static BOOL _modalOpen = false; @@ -143,7 +138,7 @@ + (void) setDebug:(BOOL)debug { _debug = debug; } + (void)setDelegate:(id)delegate{ - _delegate = delegate; + Appirater.sharedInstance.delegate = delegate; } + (void)setUsesAnimation:(BOOL)animation { _usesAnimation = animation; @@ -268,7 +263,6 @@ + (Appirater*)sharedInstance { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ appirater = [[Appirater alloc] init]; - appirater.delegate = _delegate; appirater.eventQueue = [[NSOperationQueue alloc] init]; appirater.eventQueue.maxConcurrentOperationCount = 1; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive) name: diff --git a/CHANGELOG.md b/CHANGELOG.md index ed64ce60..b71b13ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ Unreleased: * Use SKStoreReviewController if available * Available on iOS > 10.3 * You'll need to link the StoreKit Framework +* Armenian localization +* Fix delegate not being set after Appirater initialization (Issue #215) Version 2.1.0 *(2016-11-04)* ---------------------------- From 1b55d8cdcca952d8417d4dfd09ef3fd7d5ccb21c Mon Sep 17 00:00:00 2001 From: Arash Payan Date: Sat, 23 Sep 2017 17:08:23 -0700 Subject: [PATCH 15/16] Update README and CHANGELOG for v2.2.0 --- CHANGELOG.md | 2 +- README.md | 20 ++++---------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b71b13ed..14952d39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ Change Log ========== -Unreleased: +Version 2.2.0 *(2017-09-23)* ---------------------------- * Use SKStoreReviewController if available * Available on iOS > 10.3 diff --git a/README.md b/README.md index 3accb178..030512bf 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ Introduction --------------- -Appirater is a class that you can drop into any iPhone app (iOS 4.0 or later) that will help remind your users -to review your app on the App Store. The code is released under the MIT/X11, so feel free to -modify and share your changes with the world. Read on below for how to get started. If you need any help using, the library, post your questions on [Stack Overflow] [stackoverflow] under the `appirater` tag. +Appirater is a class that you can drop into any iPhone app (iOS 4.0 or later) that will help remind your users to review your app on the App Store. The code is released under the MIT/X11, so feel free to modify and share your changes with the world. Read on below for how to get started. If you need any help using, the library, post your questions on [Stack Overflow] [stackoverflow] under the `appirater` tag. Getting Started --------------- @@ -29,10 +27,10 @@ Configuration 4. Call `[Appirater appEnteredForeground:YES]` in your app delegate's `applicationWillEnterForeground:` method. 5. (OPTIONAL) Call `[Appirater userDidSignificantEvent:YES]` when the user does something 'significant' in the app. -###Development +### Development Setting `[Appirater setDebug:YES]` will ensure that the rating request is shown each time the app is launched. -###Production +### Production Make sure you set `[Appirater setDebug:NO]` to ensure the request is not shown every time the app is launched. Also make sure that each of these components are set in the `application:didFinishLaunchingWithOptions:` method. This example states that the rating request is only shown when the app has been launched 5 times **and** after 7 days. @@ -67,13 +65,9 @@ Appirater automatically uses `SKStoreReviewController` if available. You'll need If `SKStoreReviewController` is used, Appirater is used only to decide when to show the rating dialog to the user. Keep in mind, that `SKStoreReviewController` automatically limits the number of impressions, so the dialog might be displayed less frequently than your configured conditions might suggest. -Help and Support Group ----------------------- -Requests for help, questions about usage, suggestions and other relevant topics should be posted at the [Appirater group] [appiratergroup]. As much as I'd like to help everyone who emails me, I can't respond to private emails, but I'll respond to posts on the group where others can benefit from the Q&As. - License ------- -Copyright 2016. [Arash Payan] [arash]. +Copyright 2017. [Arash Payan] [arash]. This library is distributed under the terms of the MIT/X11. While not required, I greatly encourage and appreciate any improvements that you make @@ -83,16 +77,10 @@ Ports for other SDKs -------------- A few people have ported Appirater to other SDKs. The ports are listed here in hopes that they may assist developers of those SDKs. I don't know how closesly (if at all) they track the Objective-C version of Appirater. If you need support for any of the libraries, please contact the maintainer of the port. -+ MonoTouch Port (using C#). [Github] [monotouchport] + MonoTouch Binding (using native Appirater). [Github] [monotouchbinding] -+ Corona SDK. [Github] [coronasdkport] -+ Titanium SDK. [Github] [titaniumport] [stackoverflow]: http://stackoverflow.com/ [homepage]: https://arashpayan.com/blog/2009/09/07/presenting-appirater/ [arash]: https://arashpayan.com [Appirater.h]: https://github.com/arashpayan/appirater/blob/master/Appirater.h -[monotouchport]: https://github.com/chebum/Appirater-for-MonoTouch [monotouchbinding]: https://github.com/theonlylawislove/MonoTouch.Appirater -[coronasdkport]: https://github.com/aliasgar84/Appirater -[titaniumport]: https://github.com/mpociot/TiAppirater From 0596fd058fedd9d810cce865c1dfe5cebf40f432 Mon Sep 17 00:00:00 2001 From: Arash Payan Date: Sat, 23 Sep 2017 17:11:13 -0700 Subject: [PATCH 16/16] Update podspec for 2.2.0 release --- Appirater.podspec.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Appirater.podspec.json b/Appirater.podspec.json index b0db7193..0f5106ef 100644 --- a/Appirater.podspec.json +++ b/Appirater.podspec.json @@ -1,6 +1,6 @@ { "name": "Appirater", - "version": "2.1.0", + "version": "2.2.0", "platforms": { "ios": "5.0" }, @@ -11,7 +11,7 @@ }, "source": { "git": "https://github.com/arashpayan/appirater.git", - "tag": "2.1.0" + "tag": "2.2.0" }, "source_files": "*.{h,m}", "resource_bundles": { @@ -27,6 +27,6 @@ "weak_frameworks": "StoreKit", "license": { "type": "MIT", - "text": "Copyright 2016. Arash Payan. This library is distributed under the terms of the MIT/X11." + "text": "Copyright 2017. Arash Payan. This library is distributed under the terms of the MIT/X11." } }