Skip to content

Commit

Permalink
Merge pull request #2 from kevinchau/issue-1
Browse files Browse the repository at this point in the history
Resolves suggestions from Code Review: Issue #1
  • Loading branch information
kevinchau authored Aug 2, 2017
2 parents fbf1e9d + 65e4235 commit 821eeec
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 51 deletions.
1 change: 1 addition & 0 deletions .swift-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.1
2 changes: 1 addition & 1 deletion PoliteReview.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "PoliteReview"
s.version = "1.0.3"
s.version = "1.1.0"
s.summary = "A Polite Way to Request Reviews for iOS"
s.homepage = "https://github.com/kevinchau/PoliteReview"
s.license = { type: 'MIT', file: 'LICENSE' }
Expand Down
17 changes: 17 additions & 0 deletions PoliteReview.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
0A58206C1F30223C001FBB16 /* Frameworks */,
0A58206D1F30223C001FBB16 /* Headers */,
0A58206E1F30223C001FBB16 /* Resources */,
0A6F89861F316C58006B1636 /* ShellScript */,
);
buildRules = (
);
Expand Down Expand Up @@ -156,6 +157,22 @@
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
0A6F89861F316C58006B1636 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if which bartycrouch > /dev/null; then\n# Incrementally update all Storyboards/XIBs strings files\nbartycrouch interfaces -p \"$PROJECT_DIR\"\n\n# Add new keys to Localizable.strings files from NSLocalizedString in code\nbartycrouch code -p \"$PROJECT_DIR\" -l \"$PROJECT_DIR\" -a -s\nelse\necho \"warning: BartyCrouch not installed, download it from https://github.com/Flinesoft/BartyCrouch\"\nfi";
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
0A58206B1F30223C001FBB16 /* Sources */ = {
isa = PBXSourcesBuildPhase;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<dict>
<key>SchemeUserState</key>
<dict>
<key>PoliteReview.xcscheme</key>
<key>PoliteReview.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
Expand Down
44 changes: 21 additions & 23 deletions PoliteReview/PoliteReview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@

import Foundation


internal enum UserDefaultKeys: String {
case PoliteReviewTotalLaunchCount
case PoliteReviewVersionLaunchCount
case PoliteReviewReviewedVersion
case PoliteReviewHasReviewed
enum UserDefaultKeys: String {
case politeReviewTotalLaunchCount
case politeReviewVersionLaunchCount
case politeReviewReviewedVersion
case politeReviewHasReviewed
}

public class PoliteReview {

static private(set) internal var storeID: String = ""
static private(set) internal var contactURL: String = ""
static private(set) internal var contactEmail: String = ""
static private(set) var storeID: String = "0000000000"
static private(set) var contactURL: String = "https://www.google.com"
static private(set) var contactEmail: String = "[email protected]"
static private(set) var triggerCount: Int = 5
static public let main = PoliteReview()

public func setup(itunesID: String, contactURL: String, contactEmail: String, triggerCount: Int = 5) {
PoliteReview.storeID = itunesID
Expand All @@ -32,39 +32,37 @@ public class PoliteReview {
incrementVersionLaunch()
}

public init() {

private init() {
// init is private to force use of singleton
}

private func incrementTotalLaunch() {
// Keep track of how many times the app has been launched
let totalLaunchCount = UserDefaults.standard.integer(forKey: UserDefaultKeys.PoliteReviewTotalLaunchCount.rawValue)
UserDefaults.standard.set(totalLaunchCount + 1, forKey: UserDefaultKeys.PoliteReviewTotalLaunchCount.rawValue)
UserDefaults.standard.synchronize()
let totalLaunchCount = UserDefaults.standard.integer(forKey: UserDefaultKeys.politeReviewTotalLaunchCount.rawValue)
UserDefaults.standard.set(totalLaunchCount + 1, forKey: UserDefaultKeys.politeReviewTotalLaunchCount.rawValue)
}

private func incrementVersionLaunch() {
let currentVersion = getVersion()

// Reset the counter if the current app version is newer than a previous reviewed version
if let storedVersion = UserDefaults.standard.string(forKey: UserDefaultKeys.PoliteReviewReviewedVersion.rawValue) {
if let storedVersion = UserDefaults.standard.string(forKey: UserDefaultKeys.politeReviewReviewedVersion.rawValue) {
if currentVersion.compare(storedVersion, options: NSString.CompareOptions.numeric) != ComparisonResult.orderedDescending {
UserDefaults.standard.set(0, forKey: UserDefaultKeys.PoliteReviewVersionLaunchCount.rawValue)
UserDefaults.standard.set(0, forKey: UserDefaultKeys.politeReviewVersionLaunchCount.rawValue)
}
}

// Keep track of how many times this particular version has been launched
let currentCount = UserDefaults.standard.integer(forKey: UserDefaultKeys.PoliteReviewVersionLaunchCount.rawValue)
UserDefaults.standard.set(currentCount + 1, forKey: UserDefaultKeys.PoliteReviewVersionLaunchCount.rawValue)
UserDefaults.standard.synchronize()
let currentCount = UserDefaults.standard.integer(forKey: UserDefaultKeys.politeReviewVersionLaunchCount.rawValue)
UserDefaults.standard.set(currentCount + 1, forKey: UserDefaultKeys.politeReviewVersionLaunchCount.rawValue)
}

internal func shouldPresent() -> Bool {
func shouldPresent() -> Bool {
// Determines if a review should be presented based on a new version and if the user has been prompted before
var should = false
let currentVersion = getVersion()
let hasReviewed = UserDefaults.standard.bool(forKey: UserDefaultKeys.PoliteReviewHasReviewed.rawValue)
let versionCount = UserDefaults.standard.integer(forKey: UserDefaultKeys.PoliteReviewVersionLaunchCount.rawValue)
let hasReviewed = UserDefaults.standard.bool(forKey: UserDefaultKeys.politeReviewHasReviewed.rawValue)
let versionCount = UserDefaults.standard.integer(forKey: UserDefaultKeys.politeReviewVersionLaunchCount.rawValue)

if versionCount >= PoliteReview.triggerCount {
if let storedVersion = UserDefaults.standard.string(forKey: "reviewVersion") {
Expand All @@ -79,7 +77,7 @@ public class PoliteReview {
return should
}

internal func getVersion() -> String {
func getVersion() -> String {
// Get current app version string
guard let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else {
return "0.0.0"
Expand Down
44 changes: 23 additions & 21 deletions PoliteReview/RequestPoliteReview.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ extension UIViewController: MFMailComposeViewControllerDelegate {
// Presents a UIAlertController for the initial prompt
let appName = Bundle.main.localizedInfoDictionary?["CFBundleDisplayName"]

let alertController = UIAlertController(title: String("\(NSLocalizedString("Do you love", comment: "For the alert controller preceding the app name")) \(appName ?? "this app")?"), message: NSLocalizedString("Give Us Your Feedback", comment: "Message for the alert controller"), preferredStyle: .alert)



let alertController = UIAlertController(title: String("\(NSLocalizedString("Do you love", comment: "For the alert controller preceding the app name")) \(appName ?? NSLocalizedString("this app", comment: "Placeholder app name"))\(NSLocalizedString("?", comment: "Used for question particle"))"), message: NSLocalizedString("Give Us Your Feedback", comment: "Message for the alert controller"), preferredStyle: .alert)

// They love it action
let action1 = UIAlertAction(title: NSLocalizedString("Yes", comment: "Alert Action"), style: .default) { (UIAlertAction) in
let yesAction = UIAlertAction(title: NSLocalizedString("Yes", comment: "Alert Action"), style: .default) { (UIAlertAction) in

// Sets the reviewed status and sets the reviewed version
self.userDefaults()
self.setUserDefaultsHasReviewed()

// Requests a review via the StoreKit alert, or legacy if 10.3 is not available
if #available(iOS 10.3, *) {
Expand All @@ -34,18 +37,18 @@ extension UIViewController: MFMailComposeViewControllerDelegate {
}

// They Don't love it action
let action2 = UIAlertAction(title: NSLocalizedString("No", comment: "Alert Action"), style: .cancel) { (UIAlertAction) in
let noAction = UIAlertAction(title: NSLocalizedString("No", comment: "Alert Action"), style: .cancel) { (UIAlertAction) in
// Sets the reviewed status and sets the reviewed version
self.userDefaults()
self.setUserDefaultsHasReviewed()
// Initiates the contact process
self.contact()
}

// Adds the actions to the alert controller
alertController.addAction(action1)
alertController.addAction(action2)
alertController.addAction(yesAction)
alertController.addAction(noAction)

if PoliteReview().shouldPresent() == true {
if PoliteReview.main.shouldPresent() == true {
self.present(alertController, animated: true, completion: nil)
}

Expand All @@ -55,7 +58,7 @@ extension UIViewController: MFMailComposeViewControllerDelegate {
// Legacy alert prompts user to write a review if they are below 10.3
let legacyAlertController = UIAlertController(title: NSLocalizedString("Thank You!", comment: "Message when user love app"), message: NSLocalizedString("Please Consider Writing a Review", comment: "Ask legacy user for review"), preferredStyle: .alert)
// Action to write a review
let legacyAction1 = UIAlertAction(title: NSLocalizedString("Write Review", comment: "Alert Action"), style: .default) { (UIAlertAction) in
let legacyWriteAction = UIAlertAction(title: NSLocalizedString("Write Review", comment: "Alert Action"), style: .default) { (UIAlertAction) in
let openAppStoreForRating = "itms-apps://itunes.apple.com/us/app/id\(PoliteReview.storeID)?action=write-review&mt=8"
if UIApplication.shared.canOpenURL(URL(string: openAppStoreForRating)!) {
if #available(iOS 10.0, *) {
Expand All @@ -66,17 +69,17 @@ extension UIViewController: MFMailComposeViewControllerDelegate {
}
}
// Action to not write a review
let legacyAction2 = UIAlertAction(title: NSLocalizedString("Not Now", comment: "Alert Action"), style: .cancel, handler: nil)
let legacyDeclineAction = UIAlertAction(title: NSLocalizedString("Not Now", comment: "Alert Action"), style: .cancel, handler: nil)
// Adds the actions to the alert controller
legacyAlertController.addAction(legacyAction1)
legacyAlertController.addAction(legacyAction2)
legacyAlertController.addAction(legacyWriteAction)
legacyAlertController.addAction(legacyDeclineAction)

present(legacyAlertController, animated: true, completion: nil)
}

private func contact() {
let alertController = UIAlertController(title: NSLocalizedString("Oh No!", comment: "Alert title when user does not love your app"), message: NSLocalizedString("Let us know how to improve.", comment: "Message when user does not love your app"), preferredStyle: .alert)
let action1 = UIAlertAction(title: NSLocalizedString("Send Feedback", comment: "alert action"), style: .default) { (UIAlertAction) in
let contactAction = UIAlertAction(title: NSLocalizedString("Send Feedback", comment: "alert action"), style: .default) { (UIAlertAction) in
let appName = Bundle.main.localizedInfoDictionary?["CFBundleDisplayName"]
if MFMailComposeViewController.canSendMail() {
let composeVC = MFMailComposeViewController()
Expand All @@ -102,20 +105,19 @@ extension UIViewController: MFMailComposeViewControllerDelegate {
}
}
}
let action2 = UIAlertAction(title: NSLocalizedString("Not Now", comment: "Alert Action"), style: .cancel) { (UIAlertAction) in
let declineContactAction = UIAlertAction(title: NSLocalizedString("Not Now", comment: "Alert Action"), style: .cancel) { (UIAlertAction) in
// stuff here
}
alertController.addAction(action1)
alertController.addAction(action2)
alertController.addAction(contactAction)
alertController.addAction(declineContactAction)
self.present(alertController, animated: true, completion: nil)
}

private func userDefaults() {
private func setUserDefaultsHasReviewed() {
// Sets the reviewed status and sets the reviewed version
let currentVersion = PoliteReview().getVersion()
UserDefaults.standard.set(true, forKey: UserDefaultKeys.PoliteReviewHasReviewed.rawValue)
UserDefaults.standard.set(currentVersion, forKey: UserDefaultKeys.PoliteReviewReviewedVersion.rawValue)
UserDefaults.standard.synchronize()
let currentVersion = PoliteReview.main.getVersion()
UserDefaults.standard.set(true, forKey: UserDefaultKeys.politeReviewHasReviewed.rawValue)
UserDefaults.standard.set(currentVersion, forKey: UserDefaultKeys.politeReviewReviewedVersion.rawValue)
}

}
8 changes: 7 additions & 1 deletion PoliteReview/zh-Hans.lproj/Localizable.strings
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

/* Used for question particle */
"?" = "吗?";

/* For the alert controller preceding the app name */
"Do you love" = "你喜欢用";

Expand All @@ -24,7 +27,10 @@
"Send Feedback" = "提交意见";

/* Message when user love app */
"Thank You!" = "";
"Thank You!" = "谢谢!";

/* Placeholder app name */
"this app" = "此应用程式";

/* Alert Action */
"Write Review" = "感谢!";
Expand Down
8 changes: 7 additions & 1 deletion PoliteReview/zh-Hant.lproj/Localizable.strings
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

/* Used for question particle */
"?" = "嗎?";

/* For the alert controller preceding the app name */
"Do you love" = "你喜歡用";

Expand All @@ -24,7 +27,10 @@
"Send Feedback" = "提交意見";

/* Message when user love app */
"Thank You!" = "";
"Thank You!" = "多謝!";

/* Placeholder app name */
"this app" = "此應用程式";

/* Alert Action */
"Write Review" = "感謝!";
Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ Polite Review is an elegant way to request ratings and reviews from your users.

## Coming Soon

* Carthage Support
* Notifications for analytics within your app
* Swift 4

Expand All @@ -31,7 +30,7 @@ pod 'PoliteReview'

## Installation with Carthage
```
coming soon
github "kevinchau/PoliteReview"
```

## Usage
Expand All @@ -45,7 +44,7 @@ import PoliteReview
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
PoliteReview().setup(itunesID: <your itunes id>, contactURL: <a link to a website contact page>, contactEmail: <your contact email>, triggerCount: <a launch count>)
PoliteReview.main.setup(itunesID: <your itunes id>, contactURL: <a link to a website contact page>, contactEmail: <your contact email>, triggerCount: <a launch count>)
return true
}
```
Expand Down

0 comments on commit 821eeec

Please sign in to comment.