这是我正在开发的一项实用函数,适用于我的使用情况,可能会帮助很多其他人。(请随意批评和改进/纠正我的代码:D)。我正在开发一个语音练习应用程序,我想在用户录制几次后请求评级。我将添加主要功能,然后是其他辅助函数。简要逻辑是,您可以每年请求3次评论,因此如果
1年已过去,我将重置询问计数为0。此外,并非每次都会出现评论请求。因此,在不允许应用程序尝试评论请求之前,我设有上限为30个请求。如果应用程序版本更改,则不会考虑此限制,因为您可以再次要求新应用程序版本的评论。
func askForReview(numberOfRecordings: Int = 5) {
let defaults = UserDefaults.standard
let lastAskedReviewAt = defaults.double(forKey: lastAskedReviewAtKey)
let dateStringForLastReviewAsk = getDateString(from: lastAskedReviewAt)
let dateForLastReviewAsk = getDate(from: dateStringForLastReviewAsk) ?? Date(timeIntervalSince1970: 0)
let askedReviewToday = Calendar.current.isDateInToday(dateForLastReviewAsk)
var appReviewRequestsCount = defaults.integer(forKey: appReviewRequestsCountKey)
if Date().localDate().years(from: dateForLastReviewAsk) >= 1 {
defaults.setValue(0, forKey: appReviewRequestsCountKey)
appReviewRequestsCount = 0
}
var isAskingReviewForSameVersion = false
if let currentlyInstalledVersion = getInstalledVersionNumber(), let lastReviewAskedForVersion = defaults.string(forKey: lastReviewAskedForVersionKey) {
if currentlyInstalledVersion == lastReviewAskedForVersion {
isAskingReviewForSameVersion = true
} else {
appReviewRequestsCount = 0
defaults.setValue(0, forKey: appReviewRequestsCountKey)
}
}
let askingReviewTooManyTimes = appReviewRequestsCount >= 30 && isAskingReviewForSameVersion
let totalRecordingsTillDateCount = defaults.integer(forKey: totalRecordingsTillDateCountKey)
let localNumberOfRecordings = max(numberOfRecordings, totalRecordingsTillDateCount)
if localNumberOfRecordings > 3 && Bool.random() && !askedReviewToday && !askingReviewTooManyTimes {
SKStoreReviewController.requestReview()
defaults.setValue(Date().timeIntervalSince1970, forKey: lastAskedReviewAtKey)
if let versionNumber = getInstalledVersionNumber() {
defaults.setValue(versionNumber, forKey: lastReviewAskedForVersionKey)
}
defaults.setValue(appReviewRequestsCount + 1, forKey: appReviewRequestsCountKey)
}
}
字典键:
let lastAskedReviewAtKey = "LastAskedReviewAt"
let appReviewRequestsCountKey = "AppReviewRequestsCount"
let lastReviewAskedForVersionKey = "AskedReviewForVersion"
let appVersionNumberKey = "CFBundleShortVersionString"
辅助函数:
func getDateString(from timestamp: Double) -> String {
let dateFormatter = getDateFormatter()
let date = Date(timeIntervalSince1970: timestamp)
let dateString = dateFormatter.string(from: date)
return dateString
}
func getDate(from dateString: String) -> Date? {
let dateFormatter = getDateFormatter()
return dateFormatter.date(from: dateString) ?? nil
}
extension Date {
func years(from date: Date) -> Int {
return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
}
func months(from date: Date) -> Int {
return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
}
func weeks(from date: Date) -> Int {
return Calendar.current.dateComponents([.weekOfMonth], from: date, to: self).weekOfMonth ?? 0
}
func days(from date: Date) -> Int {
return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
}
func hours(from date: Date) -> Int {
return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
}
func minutes(from date: Date) -> Int {
return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
}
func seconds(from date: Date) -> Int {
return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
}
func offset(from date: Date) -> String {
if years(from: date) > 0 { return "\(years(from: date))y" }
if months(from: date) > 0 { return "\(months(from: date))M" }
if weeks(from: date) > 0 { return "\(weeks(from: date))w" }
if days(from: date) > 0 { return "\(days(from: date))d" }
if hours(from: date) > 0 { return "\(hours(from: date))h" }
if minutes(from: date) > 0 { return "\(minutes(from: date))m" }
if seconds(from: date) > 0 { return "\(seconds(from: date))s" }
return ""
}
}
extension Date {
func localDate() -> Date {
let nowUTC = Date()
let timeZoneOffset = Double(TimeZone.current.secondsFromGMT(for: nowUTC))
guard let localDate = Calendar.current.date(byAdding: .second, value: Int(timeZoneOffset), to: nowUTC) else {return Date()}
return localDate
}
}
func getInstalledVersionNumber() -> String? {
guard let infoDictionary = Bundle.main.infoDictionary, let currentVersionNumber = infoDictionary[appVersionNumberKey] as? String else { return nil}
return currentVersionNumber
}